本文介绍了带有CRTP可克隆类的无效协变量类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用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可克隆类的无效协变量类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-09 05:12