【问题标题】:CRTP Base to Derived ConversionCRTP 基础到派生的转换
【发布时间】:2014-09-26 07:13:51
【问题描述】:

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

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&lt;A_crtp&gt;A_crtp_base&lt;B_crtp&gt;

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

但是我必须编写自己的复制构造函数,我想避免这种情况。

有什么建议可以减少这里的编码量吗?

【问题讨论】:

    标签: c++ inheritance crtp


    【解决方案1】:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-01-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多