2014-09-26 4 views
1

을 유도하기 위해 나는 고전적인 상속을 사용하여 다음과 같은 간단한 클래스 계층 구조를 가지고 가정 :CRTP 자료가 변환

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

내가 A_classic에서 B_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

작은 제안에 자신의 변환 연산자를 정의 할 수 있습니다 : 가능하다면 당신은 일반 상속을 필요로하는 경우, 계층 구조 조금 단순화하려고 메커니즘을 사용하면 컴파일러가 다른 유형의 객체를 처리하고 객체를 어떻게하면 더 복잡하게 렌더링 할 수 있는지를 강요합니다.