2014-06-17 2 views
4

나는 다음과 같은 코드가 작동을호기심 반복 템플릿 및 템플릿 매개 변수에 따라 하위 클래스는

template < class __derived, class __object = typename __derived::Object > 
struct Base { 
    using Derived = __derived; 
    using Object = __object; 
    void function(Object o) { return Derived::function(s); } 
} 

//template < class __derived > 
//struct Base { 
// using Derived = __derived; 
// using Object = typename Derived::Object; 
// void function(Object o) { return Derived::function(s); } 
//} 

template < class __object > 
struct Derived : public Base< Derived<__Object> > { 
    using Object = __object; 
    void function(Object o) { ... } 
} 

를 만들기 위해 노력하고 문제와 문제가

Derived<double> obj; 

는, 컴파일러가없는 주장 내가 선언하여 개체를 인스턴스화 문자 ObjectDerived 클래스 내에서 찾을 수 있고 Base 클래스의 두 번째 템플릿 매개 변수를 추론 할 수 있습니다. 주석 된 버전에서도 같은 오류가 발생합니다.

나는 Eigen3 코드, 특히 가상 함수의 사용을 피하기 위해 사용하는 CRTP (Curiously Recurring Template Pattern)의 영향을 받아이 작업을 수행하려고합니다. Eigen3 실제로 traits 클래스를 사용하지만 나는 현재의 경우에 그것을 모방하는 방법을 알아낼 수 없습니다. 누구든지 이에 대해 어떤 제안이 있습니까? 미리 감사드립니다! 당신이를 사용해야합니다 있도록

template < class __object > 
struct Derived; 

불행하게도, 당신은 더 싶어 : 당신은 A가 B로부터 상속 할 경우

+0

Base' 인스턴스화 할 수 없습니다 'Derived :: Object'가 아직 존재하지 않기 때문입니다. 예, 특성 클래스를 사용하십시오. –

+3

이중 밑줄에 식별자를 사용하지 마십시오. 그것들은 C++ 구현 (컴파일러/라이브러리)을 위해 예약되어 있습니다. – dyp

+2

이것은 무엇입니까? C++ 버전의 Inception? – Praetorian

답변

4

일반적으로는, 다음, B는 선언보다 다른에 대해 아무것도 알 수 없다 유형의 특성은 다음 특성이 전혀 B을 검사하지 않기 때문에

template<class __derived> 
struct Base_traits { 
    //using Object = ?????; 
}; 
template<class __object> 
struct Base_traits<Derived<__object>> { 
    using Object = __object; //note, this also can't inspect B. 
}; 

Base 클래스는 Base_traits 모두가 원하는을 검사 할 수 있습니다. 이중 밑줄을 선도하고 관련없는

template < class __derived, class __object = typename Base_traits<__derived>::Object > 
struct Base { 
    using Derived = __derived; 
    using Object = typename Base_traits<__derived>::Object; 
    //or   
    using Object = __object; 


는 소문자 다음 밑줄 하나의 선도를 사용, 인간에 의해 사용을 위해 허용되지 않습니다. 또는 밑줄을 사용하십시오. 또한

, 구문

void function(Object o) { return Derived::function(s); } 
그 표기가 업 캐스팅 만 다운 캐스트에 사용할 수 없기 때문에

이 작동하지 않습니다. 에르고, 을 this에 사용해야합니다. 그 막연 추한 때문에, 나는 함수 뒤에 넣어 :

void foo(Object o) { self()->bar(o); } 
private: 
    __derived* self() {return static_cast<__derived*>(this);} 
    const __derived* self() const {return static_cast<__derived*>(this);} 
}; 

전체 코드 : http://coliru.stacked-crooked.com/a/81595b0fcd36ab93

`Base` 인스턴스화`끝날 때까지`Object`를 인스턴스화 할 수는 없지만 파생
+0

위대한 답변을 주셔서 감사합니다! 나는 그럭저럭 일할 수 있었다! 이제는 관련없는 또 다른 문제에 집중하고 있으므로 다른 질문을 게시 할 것입니다. 감사! – gianluca

관련 문제