从CRTP到衍生转化

从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);
}


但是然后我必须编写自己的副本构造函数,这是我想避免的。

有什么建议可以减少此处的编码量吗?

最佳答案

您可以将自己的转换运算符定义为常见的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

一个小建议:如果可能,尝试稍微简化层次结构,如果需要简单的继承机制,则将迫使编译器处理不同类型的对象,并使事情可能比它们复杂得多。

关于c++ - 从CRTP到衍生转化,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/26054006/

10-09 03:33