CRTP基于派生转换

时间:2014-09-26 07:13:52

标签: c++ inheritance crtp

假设我使用经典继承具有以下简单类层次结构:

struct A_classic {};
struct B_classic : A_classic {};

我想实现从A_classicB_classic的转换运算符。为了尽可能多地重用代码,我做了

A_classic a; // Given as input argument
B_classic b;
static_cast<A_classic&>(b) = a; // Copy A_classic's members
// Now set up B_classic's members

问题是实际上我正在使用CRTP进行继承:

template<class Derived> struct A_crtp_base {};
struct A_crtp : A_crtp_base<A_crtp> {};
template<class Derived> struct B_crtp_base : A_crtp_base<B_crtp_base<Derived>> {};
struct B_crtp : B_crtp_base<B_crtp> {};

上述技巧不再有效,因为A_crtpB_crtp的“常见”基类分别为A_crtp_base<A_crtp>A_crtp_base<B_crtp>

A_crtp a;
B_crtp b;
static_cast<A_crtp_base<???>&>(b) = a; 
// No matter what I put here, either the cast or the assignment will fail

一个明显的解决方案是模板A_crtp_base

的复制构造函数
template<class Derived>
struct A_crt_base {
   template<class OtherDerived>
   A_crtp_base(const A_crtp_base<OtherDerived>& other);
}

但是我必须编写自己的复制构造函数,我想避免使用它。

有关如何最小化编码量的任何建议吗?

1 个答案:

答案 0 :(得分:0)

您可以将自己的转换运算符定义为公共A_crtp_base

struct B_crtp;
template<class Derived> struct B_crtp_base;

template<class Derived>
struct A_crtp_base {

    operator B_crtp_base<B_crtp>();
};

struct A_crtp : A_crtp_base<A_crtp> {
    };

template<class Derived> struct B_crtp_base : A_crtp_base<B_crtp_base<Derived>> {};

struct B_crtp : B_crtp_base<B_crtp> {};

template<class Derived>
A_crtp_base<Derived>::operator B_crtp_base<B_crtp>()
{
        return B_crtp_base<B_crtp>(); // Whatever, make sure this is set with common A_crtp_base stuff
}

int main() 
{
   A_crtp a;
   B_crtp b;

   static_cast< B_crtp_base<B_crtp>& >(b) = a;

   return 0;
}

Example

一个小建议:如果可能的话,尝试稍微简化一下层次结构,如果你需要一个简单的继承机制,你就强迫编译器处理不同类型的对象并渲染可能比它们更复杂的东西是