我正在尝试使用CRTP实现Clonable类。但是,我需要抽象类具有纯虚拟克隆方法,并由子类覆盖。为此,我需要clone函数返回协变返回类型。我在下面编写了这段代码,编译器向我喊这个错误:

main.cpp:12:5: error: return type of virtual function 'clone' is not covariant with the return type of the function it overrides ('B *' is not derived from 'AbstractClonable *')

类“B”似乎是AbstractClonable的子类,甚至可以通过两种方式!我该如何解决?非常感谢你。我尝试了clang 3.6和GCC 4.9.2
struct AbstractClonable {
    virtual AbstractClonable* clone() const = 0;
};

template<typename T>
struct Clonable : virtual AbstractClonable {
    T* clone() const override {
        return new T{*dynamic_cast<const T*>(this)};
    }
};

struct A : virtual AbstractClonable {

};

struct B : A, Clonable<B> {

};

最佳答案

即使B确实是从Clonable<B>派生的,这里的问题是Clonable<B>构造无效,因为它定义了

B* clone() const override

当然,这不是AbstractClonable::clone()的替代,因为编译器此时并未将B视为AbstractClonable的子级。因此,我认为问题在于编译器无法构建Clonable<B>B基础。

解决方法(但与您想要的不完全相同)是定义
Clonable* clone() const override

Clonable中。如评论中所述,您还可以定义一个自由函数
template<typename T>
T* clone(const T* object)
{
    return static_cast<T*>(object->clone());
}

相关:Derived curiously recurring templates and covariance

10-08 13:45