3

I have a class as follows,

template<size_t N>
class A 
{
   typedef int(*ARRAY)[N];
   array getArray();

   ARRAY array;
};

Then how can I use the type ARRAY in the definition? I have tried this

template<size_t N>
ARRAY A<N>::getArray()
{
   return array;
}

But, it tells me that ARRAY is not defined.

JeJo
  • 30,635
  • 6
  • 49
  • 88
user9985127
  • 175
  • 5
  • @JesperJuhl: `typedef int (*ARRAY)[N];` – Bill Lynch Jul 27 '20 at 15:08
  • @BillLynch that's named `A::ARRAY`, as you very well know from your response. – Blindy Jul 27 '20 at 15:09
  • @Blindy: It feels petty to say they didn't define `ARRAY`, if what one really means is that you didn't give the right scope accessors to `ARRAY`. – Bill Lynch Jul 27 '20 at 15:11
  • 1
    `ARRAY A::getArray()` Before you say the function is a member of `A`, how do you expect the compiler to know where `ARRAY` is defined? It just reads from left to right. You can use a trailing return type to avoid the repetition: `auto A::getArray() -> ARRAY`. But please don't use `ALL_CAPS` for anything except macros, and don't use macros. – underscore_d Jul 27 '20 at 15:17
  • Does this answer your question? [typedef'd type not visible as return type of a member function](https://stackoverflow.com/questions/6960778/typedefd-type-not-visible-as-return-type-of-a-member-function) – underscore_d Jul 27 '20 at 15:21

3 Answers3

3

ARRAY is depended name, therefor you need to use the typename keyword before it, outside the class scope.

template<size_t N>
typename A<N>::ARRAY A<N>::getArray()
//^^^^^^^^^^^^^
{
   return array;
}

or using trailing return

template<size_t N>
auto A<N>::getArray() -> ARRAY
//                 ^^^^^^^^^^^^^
{
   return array;
}

In addition, you have a typo in your class member declaration. The

array getArray();

should be

ARRAY getArray();

However, is there any reason that you do not want to use the std::array?

JeJo
  • 30,635
  • 6
  • 49
  • 88
3

The problems is that you haven't defined a type ARRAY in the namespace, but rather within the scope of the class template. As such, the unqualified lookup doesn't find a type by that name.

Besides using a qualified name to refer to this member type alias as shown in Bill Lynch's answer, another way is to use a trailing return type in which case the name is looked up within the context of the class:

template<size_t N>
auto A<N>::getArray() -> ARRAY {
    return array;
}

P.S. I recommend highly against obfuscating the pointerness (or referenceness) of types by defining type aliases unless the alias is used in generic programming where it might be replaced by a fancy pointer (or proxy reference). In such cases the alias should conventionally be named to signify that it is a "pointer" (or "reference") such as for example in the case of type aliases of iterators and allocators and their type traits in the standard library.

eerorika
  • 232,697
  • 12
  • 197
  • 326
1
template<size_t N>
typename A<N>::ARRAY A<N>::getArray(){
    return array;
}

https://repl.it/repls/DecisiveFragrantFact

Bill Lynch
  • 80,138
  • 16
  • 128
  • 173