2010-07-29 4 views
7

인수 유형에 따라 조건부로 컴파일하려는 템플릿이 있습니다. 필자는 "일반 오래된 데이터"(POD), 즉 정수, 클래스 또는 구조체를 구별하는 것에 만 관심이 있습니다. Windows에서 C++ VS2008을 사용하고 있습니다.부스트 타입 - 특성을 사용한 조건부 컴파일

template<T> 
class foo 
{ 
    void bar(T do_something){ 
    #if IS_POD<T> 
     do something for simple types 
    #else 
     do something for classes/structs 
    #endif 
}} 

나는 부스트 라이브러리를보고 있었고, 나는 그들이 원하는 것을 가진 것처럼 보일 수있다. 그러나, 나는 문법에 대한 정확한 구문이 무엇인지 이해하지 못한다.

도움을 주시면 감사하겠습니다.


편집 --- 응답을 읽은 후, 나는 질문의 내 정의에 뭔가를 간과 참조하십시오. 클래스 fooclass type T에 대해 올바른 bar 버전 만 인스턴스화해야하는 템플릿 기반 클래스입니다. 컴파일 시간을 해결할 수있는 솔루션을 찾고있었습니다. 희망이 내 문제를 해결.

답변

7

: Boolean<true>/Boolean<false> 모두 IsPod<T>::result 반환 뭔가를 가정

. enable_if은 과부하 해결에서 템플리트 인스턴스화를 추가/제거하는 데 사용됩니다. 호출 특성을 사용하여 개체를 함수에 전달하는 가장 좋은 방법을 선택할 수 있습니다. 일반적으로 객체는 참조로 전달되어야하며 POD는 값으로 전달되어야합니다. call_traitsconstnon-const 참조 중에서 선택해 봅시다. 아래 코드는 const 참조를 사용합니다. 클래스 템플릿이 T`이 고정`, 인스턴스화되면

#include <boost/type_traits.hpp> 
#include <boost/call_traits.hpp> 

template <typename T> 
class foo { 
public: 
    void bar(typename boost::call_traits<T>::param_type obj) { 
     do_something(obj, boost::is_pod<T>()); 
    } 
private: 
    void do_something(T obj, const boost::true_type&) 
    { 
     // do something for POD 
    } 
    void do_something(const T& obj, const boost::false_type&) 
    { 
     // do something for classes 
    } 
}; 
0

여기에서는 전처리기를 사용할 수 없습니다. 대신 Boost Enable If library을보십시오.

특히, 귀하의 경우는 (테스트하지)과 같을 것이다 : 그것은 C에 대해 알고하지 않기 때문에 당신은 ++, 전처리와 함께이 문제를 해결 할 수

void bar (typename enable_if <is_pod <T>, T>::type do_something) 
{ 
    // if is POD 
} 

void bar (typename disable_if <is_pod <T>, T>::type do_something) 
{ 
    // if not 
} 
+0

이것은, 컴파일 오류가있을 것이고, 그 시점에서 당신은'전화는 두 개의 정의를 볼 수 bar' 할 때 그것은 컴파일 실패 그들 중 하나. 이것이 대체 실패가 아니기 때문에 이것이 SFINAE가 아니라는 점에 유의하십시오. 멤버의 인스턴스화 전에 유형이 고정되어 있습니다 (또는 그렇게 생각합니다.)). –

3

. (바보 같은 텍스트 대체 도구입니다.) 템플릿을 사용하여이 작업을 수행하십시오. 당신이 필요로하는 모든 유형의 특성에 따라 파견 할 수 있기 때문에, 당신은 enable_if없이 그것을 할 수

template<T> 
class foo 
{ 
    void do_something(T obj, Boolean<true> /*is_pod*/) 
    { 
     // do something for simple types 
    } 
    void do_something(T obj, Boolean<false> /*is_pod*/) 
    { 
     // do something for classes/structs 
    } 

    void bar(T obj) 
    { 
     do_something(obj, IsPod<T>::result()); 
    } 
}