簡體   English   中英

從CRTP到衍生轉化

[英]CRTP Base to Derived Conversion

假設我具有以下使用經典繼承的簡單類層次結構:

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的“公共”基類B_crtpA_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的副本構造函數進行模板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;
}

一個小建議:如果可能,嘗試稍微簡化層次結構,如果需要簡單的繼承機制,則將迫使編譯器處理不同類型的對象,並使事情變得比它們復雜得多。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM