在模板虚拟类层次结构中调用基类方法

jay*_*ica 4 c++ virtual templates

假设我有以下类层次结构:

template< class T >
class TestBase {

public:

    virtual T const & do_foo() = 0;

};

template< class T >
class TestDerived : public virtual TestBase< T > {

public:

    virtual int do_bar() {
        return do_foo() + 1;
    }

};
Run Code Online (Sandbox Code Playgroud)

海湾合作委员会吐出以下内容:

error: there are no arguments to ‘do_foo’ that depend on a template parameter, so a declaration of ‘do_foo’ must be available [-fpermissive]
note: (if you use ‘-fpermissive’, G++ will accept your code, but allowing the use of an undeclared name is deprecated)
Run Code Online (Sandbox Code Playgroud)

现在,如果我将其更改为从已知类型实例化的TestBase派生(例如class TestDerived : public virtual TestBase< int >,此代码段编译得很好,所以问题显然与编译时未知的基类类型有关.但是因为我没有实例化对象任何一个类的任何一个,我不明白为什么这甚至应该重要.

基本上,如何在不诉诸的情况下解决错误-fpermissive?

Rei*_*ica 8

在解析模板时,不会在实例化时查找非依赖名称(即,不依赖于模板参数的名称).您需要创建do_foo一个从属名称.基本上有两种方法可以实现这一目标:

virtual int do_bar() {
    return this->do_foo() + 1;
}
Run Code Online (Sandbox Code Playgroud)

要么

template< class T >
class TestDerived : public virtual TestBase< T > {

public:
    using TestBase<T>::do_foo;

    virtual int do_bar() {
        return do_foo() + 1;
    }

};
Run Code Online (Sandbox Code Playgroud)

  • @KonradRudolph这会改变语义.如果您使用我列出的方式之一,动态分派(虚拟呼叫)将正常工作.如果明确限定,则绕过动态调度. (5认同)