2016-09-30 49 views
4

我的enable_if語句變得非常長,所以我想以某種方式typedef。我不確定最好的方法是什麼。如何在結構中連接std :: is_same

我嘗試這樣做,但它不工作

template<typename T> 
struct isValidImageFormat 
{ 
    typedef 
     typename std::is_same<T, float>::value || 
     typename std::is_same<T, unsigned char>::value 
     value; 
}; 

的錯誤是:

預期不合格-ID»||«令牌 類型名稱的std :: is_same ::值||

問題:

  • 什麼是錯我的代碼?
  • 什麼是一個很好的解決我的問題?
+2

'的std :: is_same :: value'是不是一個類型的,所以你的整個'typedef'和'typename'業務是沒有意義的首先。 –

回答

11

你想std::disjunction(花式哲學的 「或」 字):

typedef std::disjunction< 
    std::is_same<T, float>, 
    std::is_same<T, unsigned char>> condition; 

然後你可以使用condition::value得到一個true或false值。或者,如果你只想要一個值,試試這個:當你想與類型工作

constexpr bool condition = 
    std::is_same<T, float>::value || 
    std::is_same<T, unsigned char>::value; 
+1

我會提到'std :: disjunction'是C++ 17的一部分。這可能不是OP的可行解決方案。 – skypjack

5

typename關鍵字時,在你的例子,你想與constexpr bool值繼續工作。

template<typename T> 
struct isValidImageFormat 
{ 
    constexpr static bool value = 
     std::is_same<T, float>::value || 
     std::is_same<T, unsigned char>::value; 
}; 
2

使用該方法,isValidImageFormat<T>結果總是要麼一個std::true_typestd::false_type

#include <utility> 
#include <iostream> 

template<typename T> 
struct isValidImageFormatImpl 
{ 
    static constexpr bool match = std::is_same<T, float>::value 
    or std::is_same<T, unsigned char>::value; 

    using type = std::conditional_t<match, std::true_type, std::false_type>; 
}; 


template<typename T> 
using isValidImageFormat = typename isValidImageFormatImpl<T>::type; 

int main() 
{ 
    std::cout << isValidImageFormat<float>() << '\n'; 
    std::cout << isValidImageFormat<int>() << '\n'; 

    static_assert(std::is_same<isValidImageFormat<float>, std::true_type>(), ""); 
    static_assert(std::is_same<isValidImageFormat<int>, std::false_type>(), ""); 

} 

預期輸出:

1 
0 
2

你並不需要一個結構實際上。由於C++ 14,你可以很容易地使用一個變量的模板:

#include <type_traits> 

template<typename...> 
constexpr bool isValidImageFormatVar = false; 

template<typename T, typename U, typename... O> 
constexpr bool isValidImageFormatVar<T, U, O...> = std::is_same<T, U>::value || isValidImageFormatVar<T, O...>; 

template<typename T> 
constexpr bool isValidImageFormat = isValidImageFormatVar<T, float, unsigned char>; 

int main() { 
    static_assert(isValidImageFormat<float>, "!"); 
    static_assert(isValidImageFormat<unsigned char>, "!"); 
    static_assert(not isValidImageFormat<int>, "!"); 
}