9

I can't believe gcc won't accept the following code... Please tell me if accessing an inner class from a base template is really not possible or am i missing something?

template <class T> class BaseClass
{
public:
    struct MyStruct
    {
        T *data;
    };
};

template <class T> class ChildClass : public BaseClass <T>
{
    public:

    void problem()
    {
        MyStruct ms1; //error: 'MyStruct' was not declared in this scope
        ::MyStruct ms2; //error: '::MyStruct' has not been declared
        BaseClass<T>::MyStruct ms3; //error: expected `;' before 'ms3'
    }
};
David Rodríguez - dribeas
  • 204,818
  • 23
  • 294
  • 489
Ryan
  • 1,451
  • 2
  • 27
  • 36
  • I have edited the question to make it more obvious what the problem is about. Initially it sounded like you were inheriting from an inner class, and templates were not mentioned anywhere (but the code) in the question, while they are the actual issue at hand. – David Rodríguez - dribeas May 16 '11 at 08:03

2 Answers2

15

The problem is that MyStruct is a dependent name, so you have to tell the compiler to defer name lookup until the template is instantiated by qualifying it with the base class name:

typename BaseClass<T>::MyStruct ms1;

For more information, I'd read the Parashift C++ FAQ entry, "Why am I getting errors when my template-derived-class uses a nested type it inherits from its template-base-class?"

James McNellis
  • 348,265
  • 75
  • 913
  • 977
6
BaseClass<T>::MyStruct ms3;

Should be

typename BaseClass<T>::MyStruct ms3;

Since the MyStruct is a dependent name, i.e., it depends on the template argument.
Relevant: Where and why do I have to put “template” and “typename” on dependent names?

Community
  • 1
  • 1
Xeo
  • 129,499
  • 52
  • 291
  • 397