24

When a template publicly inherits from another template, aren't the base public methods supposed to be accessible?

template <int a>
class Test {
public:
    Test() {}
    int MyMethod1() { return a; }
};

template <int b>
class Another : public Test<b>
{
public:
    Another() {}
    void MyMethod2() {
        MyMethod1();
    }
};

int main()
{
    Another<5> a;
    a.MyMethod1();
    a.MyMethod2();
}

Well, GCC craps out on this... I must be missing something totally obvious (brain melt). Help?

rubenvb
  • 74,642
  • 33
  • 187
  • 332
OldCoder
  • 251
  • 1
  • 2
  • 3

5 Answers5

32

This is part of the rules concerning dependent names. Method1 is not a dependent name in the scope of Method2. So the compiler doesn't look it up in dependent base classes.

There two ways to fix that: Using this or specifying the base type. More details on this very recent post or at the C++ FAQ. Also notice that you missed the public keyword and a semi-colon. Here's a fixed version of your code.


template <int a>
class Test {
public:
    Test() {}
    int MyMethod1() { return a; }
};

template <int b>
class Another : public Test<b>
{
public:
    Another() {}
    void MyMethod2() {
        Test<b>::MyMethod1();
    }
};

int main()
{
    Another<5> a;
    a.MyMethod1();
    a.MyMethod2();
}

kynan
  • 13,235
  • 6
  • 79
  • 81
Leandro T. C. Melo
  • 3,974
  • 22
  • 22
14

You should fully qualify MyMethod1. C++ Standard clearly states this in 14.6.2/3:

In the definition of a class template or a member of a class template, if a base class of the class template depends on a template-parameter, the base class scope is not examined during unqualified name lookup either at the point of definition of the class template or member or during an instantiation of the class template or member.

So, you should write:

void MyMethod2() {
    Test<b>::MyMethod1();
}
Kirill V. Lyadvinsky
  • 97,037
  • 24
  • 136
  • 212
  • 2
    And if you are wondering "**why** the stupid restriction when *base class of the class template depends on a template-parameter*?", see [In a templated derived class, why do I need to qualify base class member names with “this->” inside a member function?](http://stackoverflow.com/questions/7908248/in-a-templated-derived-class-why-do-i-need-to-qualify-base-class-member-names-w/7908530#7908530) – curiousguy Aug 16 '12 at 17:04
2

main needs a return type.

class Another needs a terminating semi-colon.

class Another needs its members to be public.

Also, methods aren't generally considered invisible; the methods were inaccessible without the public access keyword.

sean e
  • 11,792
  • 3
  • 44
  • 56
  • 2
    It's fine to omit a return statement in main() according to the c++ standard, in which case 0 is returned. – TC. Oct 14 '09 at 17:27
  • IOW - I meant the type was missing from the decl, rather than a return value in the body of main. – sean e Oct 14 '09 at 17:34
1

I cleaned up your code to this:

template <int a>
class Test {
public:
    Test() {}
    int MyMethod1() { return a; }
};

template <int b>
class Another : public Test<b>
{
public:
    Another() {}
    void MyMethod2() {
        MyMethod1();
    }
};


int main()
{
    Another<5> a;
    a.MyMethod1();
    a.MyMethod2();
}

And compiled with -fpermissive with no problems (you can probably resolve this issue).

John Ledbetter
  • 13,557
  • 1
  • 61
  • 80
  • 1
    This still has an error (it shouldn't compile in a standard conformant compiler). See my post below. – Leandro T. C. Melo Oct 14 '09 at 17:26
  • MSVC will build this as long as Disable Language Extensions is off (the default). – Dolphin Oct 14 '09 at 17:43
  • That's because VC doesn't to proper two-phase lookup. Symbols are, basically, only looked up when the template is instantiated. (I think it does a little bit more, but just barely. It's amazing what kind of stupid mistakes go unnoticed without two-phase lookup until someone instantiates the template. If you wrote the template, that can be quite embarrassing.) – sbi Oct 17 '09 at 12:48
0

I think you are just missing a public: at the top of the Another definition. For questions like this it is usually helpful to post the error messages that you are getting.

Dolphin
  • 4,655
  • 1
  • 30
  • 25