派生类中非虚函数的C++同名与`final`说明符冲突

dav*_*igh 0 c++ inheritance templates crtp c++14

这有一个完整的新手问题的感觉,但为什么下面的代码不能编译时使用final说明符B::operator()

struct A
{
    virtual void operator()() const = 0;
};

// the CRTP-component is not really necessary here
// but it possibly makes more sense in that it could be applied like this in reality
//
template<typename Derived>
struct B : A
{
    virtual void operator()() const override final
    {
        static_cast<Derived const&>(*this).operator()();
    }
};

struct C : B<C>
{
    void operator()() const
    {
        //do something
    }
};

int main()
{
    C()();
}
Run Code Online (Sandbox Code Playgroud)

G ++打印以下错误消息:

main.cpp:17:14: error: virtual function 'virtual void C::operator()() const'
         void operator()() const
              ^
main.cpp:9:22: error: overriding final function 'void B<Derived>::operator()() const [with Derived = C]'
         virtual void operator()() const override final
                      ^
Run Code Online (Sandbox Code Playgroud)

我本以为它可以工作,因为非虚拟C::operator()不会覆盖其基类中的虚函数?我怎样才能使这个工作( - 不改变名称C::operator())?


编辑:正如几个用户所指出的,答案很简单,virtual派生类中的-keyword是多余的(而我认为将其删除会阻止继承).但是,我在提出这个问题时的目标 - 即整个动态和静态继承层次结构中的一致接口 - 可以通过使用非虚拟的operator[]遍历和成对类A以及B虚函数来解决apply:

struct A
{
    void operator()() const
    {
        this->apply();
    }

protected:
    virtual void apply() const = 0;
};

template<typename Derived>
struct B : A
{
    void operator()() const
    {
        static_cast<Derived const&>(*this).operator()();
    }

protected:
    virtual void apply() const override final
    {
        this->operator()();
    }
};

struct C : B<C>
{
    void operator()() const
    {
        //do something
    }
};

int main()
{
    C()();
}
Run Code Online (Sandbox Code Playgroud)

Bri*_*ian 6

如果virtual在基类中声明了一个函数,那么使用相同名称和参数列表声明的函数隐式virtual在派生类中,无论您是否使用该virtual关键字.你不能做C::operator()()非虚拟的.