2016-11-04 34 views
1

我有一个函数模板,我想限制它可以实例化的类型的集合。定义一个自定义谓词作为std :: is_same的组合

我写了这样的事情:

template <typename T> 
void DoSomething(/* ... Some parameters involving T ... */) 
{ 
    // Check at compile-time that T is allowed 
    static_assert(
     std::is_same<T, int>::value 
     || std::is_same<T, float>::value 
     || std::is_same<T, double>::value 
     ... 
     || std::is_same<T, /* other type */>::value, 
     "Type not allowed"); 
} 

我不得不重复其他函数模板相同的检查。

一个明显的解决方案是复制并粘贴上述static_assert检查,但这会对代码可维护性造成影响。

更好的解决方案可能是将static_assert检查包装在专用辅助函数中,并在每个需要类型检查的函数模板中调用它。

但我觉得这是更优雅是定义一个自定义组合std::is_same电话,我可以使用这样的:

static_assert(IsTypeAllowed<T>::value, "Type not allowed"); 

我如何定义我的自定义IsTypeAllowed<T>作为std::is_same呼叫组合||'在一起?

+2

如果你只是想排除整数类型,你可以使用[' std :: is_integral '](http://en.cppreference.com/w/cpp/types/is_integral)。 –

+0

@πάνταῥεῖ:谢谢,我知道'std :: is_integral',但它是一个特定的子集选择(也有其他自定义类型)。 –

回答

1

在C++ 1Z你可以std::disjunction推出自己的特点:

template<typename T, typename... Others> 
struct is_any : std::disjunction<std::is_same<T, Others>...> 
{ 
}; 

然后,它的那样简单

static_assert(!is_any<int,char,bool>::value); 
//static_assert(!is_any<int,char,bool,int>::value); //error 

demo

您可以进一步映射它来获得您要求的确切界面:

template<typename T> 
using IsTypeAllowed = std::bool_constant<!is_any<T, char, bool, int>::value>; 

如果您需要在C++ 14,你不用看父亲比cppreference提供了可能的实现:

template<class...> struct disjunction : std::false_type { }; 
template<class B1> struct disjunction<B1> : B1 { }; 
template<class B1, class... Bn> 
struct disjunction<B1, Bn...> 
    : std::conditional_t<B1::value != false, B1, disjunction<Bn...>> { };