2014-11-15 2 views
0

템플릿 매개 변수 유형이 통합되어 있는지 어떻게 확인할 수 있습니까?통합형 검사

C++ 11에서 std::is_integral<>을 사용할 수 있음을 알고 있습니다. 여기에도 문제가 있습니다.

How to check that template's parameter type is integral?

나는 또한 부스트를 알고는이 기능을 제공합니다. 이 수표를 "수동으로"만드는 방법에 관심이 있습니다.

해결하려는 문제가 없습니다. 이것은 C++에 대한 추상적 인 질문입니다. 기본 케이스와 일부 리디렉션 사례와 특성 클래스를 정의를 시작 그 후

template<bool B> 
struct bool_type { 
    static const bool value = B; 
}; 

typedef bool_type<true> true_type; 
typedef bool_type<false> false_type; 

:

+0

아마도 부스트 코드베이스가이 답변을 직접 제공 할 수 있습니까? 예, 코드를 샅샅이 뒤져서 어떻게 끝났는지 확인합니다 ... – abiessu

+0

내가 아는 두 가지 주요 방법은 각각의 정수형을 전문화하거나 유형 목록을 작성하고이를 살펴 보는 것입니다. – chris

+0

@abiessu 나는 게으르다하지만 솔직히 Boost 코드를 읽기가 어렵다고 생각하고 질문을함으로써 대체 방법을 제시하는 완전한 설명을 얻을 수 있습니다. – Praxeolitic

답변

4

수동으로 먼저 컴파일 시간에 뭔가 이 거짓의 사실 여부를 정의하는 템플릿 클래스를 정의 할 필요가 말하기 :

template<typename T> 
struct is_integral : false_type {}; 

template<typename T> 
struct is_integral<const T> : is_integral<T> {}; 

template<typename T> 
struct is_integral<volatile T> : is_integral<T> {}; 

그러면 통합 유형의 템플릿 전문화를 수동으로 인스턴스화하여 코어가 생성됩니다.

template<> 
struct is_integral<int> : true_type {}; 

template<> 
struct is_integral<long> : true_type {}; 

// etc 

어쨌든 그렇게하는 방법 중 하나입니다. 매크로를 쉽게 생성 할 수있는 매크로를 만들 수 있습니다. 그러나 기본 아이디어는 동일하게 유지됩니다. 특정 유형이 요청하는 그룹의 일부인지 확인하고 일종의 조회를 통해 완료되었는지 확인합니다. 이 방법 (명시 적 템플릿 인스턴스화)은 아마도이를 수행하는 가장 쉬운 방법 일 것입니다.

+0

정수 타입에 대해서는 실패하지만 부동 소수점 타입에는 실패하는 코드가 있었으면 좋겠지 만 확실히 질문에 답합니다. – Praxeolitic

+0

@Praxeolitic 그들은 실제로 실패하지 않습니다 - 어떤 특성도 실제로 않습니다 - 그들은':: value' 대신'true' 대신'false'를 반환합니다. – Rapptz

+0

@Praxeolitic, 당신은 확실히 그것을 사용하여 컴파일 실패 코드를 만들 수 있습니다. 'static_assert (! is_integral :: 값, "");' – chris

1

이 될 수 "링크 전용" 대답하지만, 질문,

가능한 구현 대답 IMHO :

라인

다른 typedef들뿐만 아니라 위의 코드를 참조하십시오 256 From GCC 4.8.1 Online Docs로를 라인 151.

0

숫자 형식이 정수인지 또는 소수 부분을 가질 수 있는지를 결정하기 위해 이와 같은 작업을 수행 할 수 있습니다. 이 코드는 숫자가 아닌 형식으로는 컴파일되지 않지만 원하는 경우 임의의 형식을 필터링하기 위해 추가 메타 프로그래밍을 추가 할 수 있습니다. 정적 bool 값 대신 "true"유형 또는 "false"유형 (예 : Rapptz '응답)을 제공하도록 수정 될 수도 있습니다.

필자는 형식이 아닌 값을 테스트하는 두 가지 방법을 제시했습니다. 하나는 decltype을 사용하여 유형을 가져오고 다른 하나는 템플릿 함수를 사용합니다. 이 함수는 decltype을 사용할 수없는 경우 사용할 수 있지만 그 결과는 런타임에만 사용할 수 있습니다 (decltype이 아닌 경우에는 constexpr을 사용할 수 없습니다).

VALUE_IS_INTEGER 매크로 및 value_is_integer 템플릿 함수는 주어진 값이 정수인지 아닌지 테스트하지 않고 값 유형이 정수인지 여부를 테스트합니다.

#include <iostream> 

template <typename T, bool IS_INTEGRAL = T(3)/T(2)<=T(1) || T(3)/T(2)>=T(2)> 
    struct IsIntegerTypeCheck { 
    static const bool is_integer = IS_INTEGRAL; 
}; 

#define TYPE_IS_INTEGER(type) (IsIntegerTypeCheck<type>::is_integer) 
#define VALUE_IS_INTEGER(value) (IsIntegerTypeCheck<decltype(value)>::is_integer) 

template <typename T> static bool value_is_integer(const T& value) { 
    return IsIntegerTypeCheck<T>::is_integer; 
} 

template <typename ST> 
void dump_bool(ST message, bool value) { 
    std::cout << message << ' ' << (value ? "true" : "false") << "\n"; 
} 

int main() { 
    static const bool int_is_integer = TYPE_IS_INTEGER(int); 
    static const bool float_is_integer = TYPE_IS_INTEGER(float); 
    static const long unity = 1; 
    static const double tau = 3.1415925 * 2; 
    static const bool unity_is_integer = VALUE_IS_INTEGER(unity); 
    static const bool tau_is_integer = value_is_integer(tau); 
    dump_bool("int is integer: ", int_is_integer); 
    dump_bool("float is integer:", float_is_integer); 
    dump_bool("unity is integer:", unity_is_integer); 
    dump_bool("tau is integer: ", tau_is_integer); 
    return 0; 
} 
관련 문제