每个派生类的复制构造函数



考虑以下代码。我希望convert函数可以工作,而不需要在Base的每个具体派生类型中定义T(const Base&)复制构造函数。在中间类CRTP<T>中,只有当它不是抽象的,但它是抽象的,才可以按所示的方法来实现。那么在这种情况下,我该如何让它起作用呢?

struct Base {
virtual void foo() = 0;
};
template <typename T>
struct CRTP : virtual Base {
CRTP (const Base& base) : Base(base) { }
CRTP() = default;
//  virtual void foo() override { }  // CRTP<T> is abstract.
};
struct Derived1 : CRTP<Derived1> {
Derived1 (const Base& base) : Base(base) { }
Derived1() = default;
virtual void foo() override { }
};
struct Derived2 : CRTP<Derived1> {
Derived2 (const Base& base) : Base(base) { }
Derived2() = default;
virtual void foo() override { }
};
template <typename T, typename U>
T* convert (const U& u) {
//  return new T(u);  // This works, but only if T(const Base&) constructor is defined in every Base concrete derived type.
return dynamic_cast<T*>(new CRTP<T>(u));  // This only works if CRTP<T> is not abstract.
}
int main() {
Derived1 d1;
Derived2* d = convert<Derived2, Derived1>(d1);
}

但是,事实上,它不是一个复制构造函数,所以它可以简单地像这样委托:

struct Derived1 : CRTP<Derived1> {
using CRTP<Derived1>::CRTP;
Derived1() = default;
virtual void foo() override {
}
};

还可以使用指针而不是引用,顺便说一下,这在代码中似乎更相关,因为convert()返回指针。这样的构造函数不被认为是复制构造函数,并且总是可以委托给子构造函数。

最新更新