开发者

Inheritance and templates in C++ - why are inherited members invisible?

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开发者_StackOverflow社区 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?


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();
}


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();
}


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.


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).


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜