2014-09-26 21 views
1

假設我有使用傳統的繼承下面簡單的類層次結構: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_crtp,B_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); 
} 

但後來我不得不寫我自己的拷貝構造函數,這是我想避免的。

任何建議如何最大限度地減少編碼在這裏?

回答

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

一個小小的建議:如果可能的話儘量簡化你的層次了一下,如果你需要一個普通的繼承機制,你迫使編譯器處理不同類型的對象,並且渲染事物可能比它們可能更復雜。