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

时间:2009-10-14 17:17:28

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

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

5 个答案:

答案 0 :(得分:31)

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

有两种方法可以解决这个问题:使用this或指定基本类型。有关此very recent postC++ 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();
}

答案 1 :(得分:14)

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

  

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

所以,你应该写:

void MyMethod2() {
    Test<b>::MyMethod1();
}

答案 2 :(得分:2)

main需要返回类型。

类另一个需要终止分号。

类另一个需要其成员公开。

此外,通常认为方法不可见;没有公共访问关键字,方法无法访问。

答案 3 :(得分:1)

我清理了你的代码:

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

使用-fpermissive编译没有问题(你可以解决这个问题)。

答案 4 :(得分:0)

我认为你只是错过了一个公众:在另一个定义的顶部。对于这样的问题,发布您收到的错误消息通常很有帮助。