20

Here is a simplified example:

template<typename T>
class MyTemplate
{
  class Inner {};
  Inner met();
};

template<typename T>
MyTemplate<T>::Inner  MyTemplate<T>::met()
{ }

I get the following compilation error:

expected constructor, destructor, or type conversion before 'met'

I use GCC. It seems the compiler doesn't recognize MyTemplate<T>::Inner as a proper class. How can I fix this? I've tried sticking the typename keyword here and there to no avail. Right now, the only way I can manage to compile this is to inline the method definition in the class declaration, which I would like to avoid.

Praetorian
  • 106,671
  • 19
  • 240
  • 328
lampyridae
  • 949
  • 1
  • 8
  • 21
  • 1
    `typename MyTemplate::Inner MyTemplate::met()` and my GCC 4.6 is happy with your code. Which version of GCC are you using? – mkaes Nov 23 '11 at 17:06

3 Answers3

32

Clang reports the following:

error: missing 'typename' prior to dependent type name
'MyTemplate<T>::Inner' MyTemplate<T>::Inner  MyTemplate<T>::met()
^~~~~~~~~~~~~~~~~~~~ typename  1 error generated.

And placing typename in the appropriate place fixes it.

template<typename T>
class MyTemplate
{
  class Inner {};
  Inner met();
};

template<typename T>
typename MyTemplate<T>::Inner  MyTemplate<T>::met()
{ }

Did you put typename in the correct location? If so, then this must be a bug in G++.

Michael Price
  • 8,088
  • 1
  • 17
  • 24
13

The return type of MyTemplate::met is a dependent name, so you need to add the typename keyword before it. The following compiles on gcc-4.5.1

template<typename T>
struct MyTemplate
{
  class Inner {};
  Inner met();
};

template<typename T>
typename MyTemplate<T>::Inner  MyTemplate<T>::met()
{
  return typename MyTemplate<T>::Inner();
}

int main()
{
  MyTemplate<int> foo;

  MyTemplate<int>::Inner bar = foo.met();
}
Praetorian
  • 106,671
  • 19
  • 240
  • 328
2

You need to add typename keyword before MyTemplate<T>::Inner because MyTemplate<T> is a dependent scope.

Prasoon Saurav
  • 91,295
  • 49
  • 239
  • 345