C++中的继承和模板 - 为什么继承成员不可见?

Old*_*der 22 c++ inheritance templates

当模板公开继承自另一个模板时,不是应该可访问的基本公共方法吗?

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();
}
Run Code Online (Sandbox Code Playgroud)

好吧,海湾合作委员会对此嗤之以鼻......我必须遗漏一些完全明显的东西(大脑融化).救命?

Lea*_*elo 31

这是有关从属名称的规则的一部分.Method1不是范围内的依赖名称Method2.所以编译器不会在依赖的基类中查找它.

有两种方法可以解决这个问题:使用this或指定基本类型.关于这篇最近的帖子C++ FAQ的更多细节.另请注意,您错过了public关键字和分号.这是您的代码的固定版本.


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

Run Code Online (Sandbox Code Playgroud)

  • 是的,这是正确的答案.(注意,TTBOMK,`this-> MyMethod1()`也应该有效.) (8认同)
  • 如果您认为这是必要的,那么您并不孤单.尽管如此,它仍然是生活中令人遗憾的事实. (4认同)

Kir*_*sky 14

你应该完全符合资格MyMethod1.C++标准在14.6.2/3中清楚地说明了这一点:

在类模板的定义或类模板的成员中,如果类模板的基类依赖于模板参数,则在类的定义时,在非限定名称查找期间不会检查基类作用域.模板或成员或在类模板或成员的实例化期间.

所以,你应该写:

void MyMethod2() {
    Test<b>::MyMethod1();
}
Run Code Online (Sandbox Code Playgroud)

  • 如果你想知道"**为什么**类模板的*基类取决于模板参数*?时的愚蠢限制",请参阅[在模板化的派生类中,为什么我需要限定基类成员名称在成员函数中使用"this->"?](http://stackoverflow.com/questions/7908248/in-a-templated-derived-class-why-do-i-need-to-qualify-base-class -member-名-W/7908530#7908530) (2认同)

Dol*_*hin 0

我认为你只是缺少一个公众:在另一个定义的顶部。对于此类问题,发布您收到的错误消息通常会有所帮助。