如何在struct中连接std :: is_same

时间:2016-09-30 11:29:52

标签: c++ templates

我的enable_if语句变得很长,所以我想以某种方式输入typedef。我不确定最好的方法是什么。

我尝试了这个,但它不起作用

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

错误是:

  

在“||”标记之前预期的非限定标识                    typename std :: is_same :: value ||

问题:

  • 我的代码出了什么问题?
  • 什么是我的问题的好方法?

4 个答案:

答案 0 :(得分:11)

你想要std::disjunction(哲学中用于“或”的奇特单词):

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

然后您可以使用condition::value来获取真值或假值。或者,如果您只想要一个值,请尝试:

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

答案 1 :(得分: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 :(得分: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

答案 3 :(得分: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>, "!");
}