问题描述
我正在尝试使用CRTP实现一个Clonable类.但是,我需要抽象类具有纯虚拟克隆方法,并由子类覆盖.为此,我需要clone函数返回协变返回类型.我在下面编写了这段代码,编译器向我大喊这个错误:
I'm trying to implement a Clonable class with the CRTP. However, I need to have abstract class that have a pure virtual clone method, overridden by child classes. To make this happen, I need the clone function to return a covariant return type. I made this code below, and the compiler shout at me this error:
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
The class 'B' seems to be a child class of AbstractClonable, and even by two way! How can I solve this? Thank you very much. I tried with both with clang 3.6 and 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>构造无效,因为它定义了
Even if B is indeed derived from Clonable<B>, the problem here is that Clonable<B> construction is not valid, as it defines
B* clone() const override
这当然不是对AbstractClonable::clone()的替代,因为编译器此时并未将B视为AbstractClonable的子级.因此,我认为问题在于编译器无法建立B的Clonable<B>基.
which of course is not an override of AbstractClonable::clone(), since the compiler doesn't see B at this point as a child of AbstractClonable. So I believe the issue lays in the fact that the compiler cannot build the Clonable<B> base of B.
一种解决方法(但与您想要的不完全相同)是
A workaround (but not really the same as what you want) is to define
Clonable* clone() const override
中的
.正如您在评论中提到的那样,您还可以定义一个自由函数
in Clonable. As you mentioned in the comment, you can also define a free function
template<typename T> T* clone(const T* object) { return static_cast<T*>(object->clone()); }
这篇关于带有CRTP可克隆类的无效协变量类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!