1

I'm having difficulty understanding why there is a difference in the following two pieces of code, what exactly is the compiler doing.

I have the following bit of trivial code, that compiles without any problems as expected:

class base
{
public:
   typedef int booboo;
};

class derived : public base
{
public:
   int boo()
   {
      booboo bb = 1;
      return bb;
   }
};

int main()
{
   derived d;
   d.boo();
   return 0;
}

I take the code from above and add some template parameters, and begin to get errors relating the type booboo not being valid:

template <typename T>
class base
{
public:
   typedef T booboo;
};

template <typename T>
class derived : public base<T>
{
public:
   //typedef typename base<T>::booboo booboo; <-- fixes the problem
   booboo boo()
   {
      booboo bb = T(1);
      return bb;
   }
};

int main()
{
   derived<int> d;
   d.boo();
   return 0;
}

Error:

prog.cpp:13:4: error: ‘booboo’ does not name a type
prog.cpp:13:4: note: (perhaps ‘typename base<T>::booboo’ was intended)
prog.cpp: In function ‘int main()’:
prog.cpp:23:6: error: ‘class derived<int>’ has no member named ‘boo’

http://ideone.com/jGKYIC

.

I would like to understand in details, how a typical c++ compiler goes about compiling the template version of the code, how it differs from compiling the original example, is this an issue to do with multiple passes of the code, and type dependent look-ups?

Sami Kenjat
  • 185
  • 2
  • 12

1 Answers1

3

In the second version, booboo is a dependent name, so it is not automatically visible in the template. You can either add using typename base<T>::booboo; to the derived class, or use your typedef solution, or say typename base<T>::booboo bb = T(1);.

Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
  • 5
    just for clarification, essentially what that means is that at the outset the compiler has no guarantee that there aren't specializations of the base class template that omit the definition of `booboo`, or perhaps define `booboo` as a function or whatever. so the compiler has to be told what one assumes about the name: that it comes from the base class, and that it is a type. – Cheers and hth. - Alf Mar 06 '13 at 00:47
  • @Kerrek: Would you happen to know the section in the standard that describes/talks about when types are visible when dealing with templates? or is it an implementation defined issue? – Sami Kenjat Mar 06 '13 at 00:51
  • @SamiKenjat: It's 14.6.2, "Dependent Names", in C++11. Basically any name on the right of a `::`, if the left is a template specialization. – Kerrek SB Mar 06 '13 at 01:02
  • Does that include methods? as I believe sometimes one needs to use the word "template" when invoking a template method from a class that is also templated. – Sami Kenjat Mar 06 '13 at 01:11
  • 1
    @SamiKenjat: You need to say `template` for template names, `typename` for type names, and nothing for value-like names. – Kerrek SB Mar 06 '13 at 09:04