2013-05-29 3 views
5

템플릿 클래스 내의 함수에서 기본 형식과 다른 형식을 구분하려고합니다. C++ 11에서C++ : 'std :: is_fundamental'대신 사용할 수 있습니까?

당신은 할 수 있습니다 :

if(std::is_fundamental<T>::value) 
{ 
    // Treat it as a primitive 
} 
else 
{ 
    //Treat it otherwise 
} 

내가 틀렸다이는 C++ (11)

에없는 경우 C의 이전 버전에서이 대안이 있는가 제발 올바른 ++ ?

답변

8

당신은 C++ 03과 같은에서 Boost's type traits을 사용할 수

#include <boost/type_traits/is_fundamental.hpp> 

... 

if(boost::is_fundamental<T>::value) 
{ 
    // Treat it as a primitive 
} 
else 
{ 
    //Treat it otherwise 
} 

내가이뿐만 아니라 C++ 98 작동합니다 같아요.

+0

감사합니다. '포함'에 +1. – Subway

2

이 코드를 사용하면 문제가 생길 것입니다. 서로 다른 유형 특성을 구별해야하는 경우 런타임시가 아니라 컴파일시 수행해야합니다. 수행중인 작업에 따라 if의 두 지점 중 하나가 컴파일되지 않을 수 있습니다. 따라서 특수 기능으로 전달하는 것이 좋습니다.

이 구현 기술에서는 사용 된 분기 만 컴파일 (즉, 올바른)해야합니다.

편집 :

여기에 몇 가지 추가 정보입니다. 이 문제에 대한 해결책은 템플릿의 인스턴스화와 관련이 있습니다. 작업이 실패하는 방법을 보여주기 위해 is_fundamental에서 is_array으로 전환합니다.

은 첫 번째 예제로 시작하자 :

template <class T> 
void fun(T t) { 
    if(boost::is_array<T>::value) 
    { 
     std::cout << "true" << std::endl; 
    } 
    else 
    { 
     std::cout << "false" << std::endl; 
    } 
} 

void f(int i) { 
    fun(i); 
} 

그것은 컴파일하고 실행하고 컴파일러는 if 문의 한 지점이 사용되며 사용되지 않는 코드로 다른 사람을 제거하는 것을 확인할 수 있습니다. 내 두 번째 예에서

는 내가 배열 작업을 사용하는 경우 someithing을 수행합니다

template<class T> 
void fun(T& t) { 
    if(boost::is_array<T>::value) 
    { 
     std::cout << t[0]; 
    } 
    else 
    { 
     std::cout << t; 
    } 
} 

void f(int i) { 
    fun(i); 
} 

지금은 컴파일되지 않습니다. 그 이유는 템플릿 인자 인 int가 t[0]이 형성되어 있기 때문입니다. 이 런타임 문을 사용하여 코드에 필요한 컴파일 타임에 유형 속성을 구별 할 수 없습니다 (이 예제에서는 배열 beeing의 속성과 t[0] 사용). 우리 함수 오버로드로 컴파일 시간에 disitinguish 것이다 번째 예에서

: 여기 is_array<T>::type

template<class T> 
void fun_impl(boost::true_type, T& t) { 
    std::cout << t[0]; 
} 

template<class T> 
void fun_impl(boost::false_type, T& t) { 
    std::cout << t; 
} 

template<class T> 
void fun(T& t) { 
    fun_impl(typename boost::is_array<T>::type(),t); 
} 

void f(int i) { 
    fun(i); 
} 

true_type 또는 false_type 중입니다. 이 결과는 컴파일 시간에 fun_impl의 오른쪽 오버로드를 선택하기위한 선택기로 사용되며 선택된 과부하 만 설치되고 컴파일됩니다.

일반적으로 이러한 기술은 유형에 특정 속성이있는 경우에만 편집 가능한 최상의 구현을 컴 파일 시간에 선택하는 데 사용됩니다.

2 편집 : static if 언어의 일부인 경우 물론 변화의

이됩니다.

+0

다른 접근법에서 발생할 수있는 문제에 대해 자세히 설명해 주시겠습니까? 또는 설명에 대한 참조를 추가 할 수 있습니까? 나는 네가 쓴 것을 이해하지 못했다. – Subway

+0

감사합니다. +1은 정교합니다. 나는 여전히 질문이있다 : 이해할 수있는 바와 같이, 당신의 요지는 코드를 컴파일하고 불필요한 코드의 컴파일을 저장하는 것이다. 내 코드가 컴파일 된 것을 감안할 때 첫 번째 방법을 사용하여 런타임에 발생할 수있는 실제 문제 (예기치 않은 동작)가 있습니까? – Subway

+0

@Subway no 나는 컴파일러가 상속으로 boost :: is_fundamental을보고 상수로 생각하고 사용되지 않는 코드를 제거하므로 런타임 오버 헤드가없고 UB가 없다고 생각합니다. 접근법은 컴파일하는 것입니다. const 값 멤버는 std :: enable_if (정수 템플릿 인수로)와 물론 데모 (예 : 값 인쇄)와 함께 사용하기위한 것입니다. 나는 다른 모든 목적을 위해 함수 오버로딩을 통해 둘러보기를해야한다고 생각합니다. –

관련 문제