我有一个功能模板,我想限制可以实例化的类型集。
我写了这样的话:
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
检查包装在 ad hoc 辅助函数中,并在需要进行类型检查的每个函数模板中调用它。
但我认为更优雅的是定义std::is_same
次调用的自定义组合,我可以这样使用:
static_assert(IsTypeAllowed<T>::value, "Type not allowed");
如何将自定义IsTypeAllowed<T>
定义为std::is_same
来电||
'组合在一起?
答案 0 :(得分: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
您可以进一步映射以获得您要求的确切界面:
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...>> { };