2017-03-08 6 views
0

다른 유형이 T 인 저장 유형을 지정하는 템플릿을 정의하려고합니다. 모든 산술 유형을 catch하기 위해 enable_if를 사용하고 싶습니다. 다음은 템플릿이 2 개의 매개 변수로 다시 선언되는 것에 대한 나의 시도입니다. 기본 템플릿에 두 번째 더미 매개 변수를 추가했지만 다른 오류가 발생했습니다. 어떻게 할 수 있습니까?구조체 특수화에 enable_if 사용

#include <string> 
#include <type_traits> 
template <typename T> struct storage_type; // want compile error if no match 
// template <typename T, typename T2=void> struct storage_type; // no joy 
template <> struct storage_type<const char *> { typedef std::string type; }; 
template <> struct storage_type<std::string> { typedef std::string type; }; 
template <typename T, typename std::enable_if<std::is_arithmetic<T>::value>::type* = nullptr> 
    struct storage_type { typedef double type; }; 

// Use the storage_type template to allocate storage 
template<typename T> 
class MyStorage { 
    public: 
    typename storage_type<T>::type storage; 
}; 

MyStorage<std::string> s; // uses std::string 
MyStorage<const char *> s2; // uses std::string 
MyStorage<float> f; // uses 'double' 
+0

'long double'은 'double'보다 클 수 있습니다. 또한 'long long'은 최소 64 비트이지만 더 클 수 있습니다. – NathanOliver

+0

[명백한 문제] (http://coliru.stacked-crooked.com/a/5c085b6a1f9b5a20)를 먼저 수정 하시겠습니까? –

+0

@ πάνταῥεῖ 나는 그것이 그가 묻는 것, 그 오류를 수정하는 방법이라고 생각합니다. –

답변

5

기본 템플릿에 두 번째 매개 변수를 추가 한 다음이를 적용하여이 작업을 수행 할 수 있습니다. 당신은 바른 길을 가고 있었지만 정확하게하지 않았습니다.

#include <string> 
#include <type_traits> 
// template <typename T> struct storage_type;    // Don't use this one. 
template <typename T, typename T2=void> struct storage_type; // Use this one instead. 
template <> struct storage_type<const char *> { typedef std::string type; }; 
template <> struct storage_type<std::string> { typedef std::string type; }; 

// This is a partial specialisation, not a separate template. 
template <typename T> 
struct storage_type<T, typename std::enable_if<std::is_arithmetic<T>::value>::type> { 
    typedef double type; 
}; 

// Use the storage_type template to allocate storage 
template<typename T> 
class MyStorage { 
    public: 
    typename storage_type<T>::type storage; 
}; 

MyStorage<std::string> s; // uses std::string 
MyStorage<const char *> s2; // uses std::string 
MyStorage<float> f; // uses 'double' 

// ----- 

struct S {}; 

//MyStorage<S> breaker; // Error if uncommented. 

And voila.