以下代码:
template <typename T>
struct IsOneOf<T,T> { const static bool True = true; };
template <typename T, typename ... Ts>
struct IsOneOf<T,any_of<T,Ts ...> > { const static bool True = true;};
template <typename T, typename T2,typename ... Ts>
struct IsOneOf<T,any_of<T2,Ts ...> > {
const static bool True = IsOneOf<T,T2>::True ||
IsOneOf<T,any_of<Ts ...> >::True;
};
template <typename T1, typename ... Ts1, typename ... Ts2>
struct IsOneOf< any_of<T1,Ts1 ...>, any_of<Ts2 ...> > {
const static bool True = IsOneOf<T1,any_of<Ts2 ...> >::True &&
IsOneOf<any_of<Ts1...>, any_of<Ts2 ...> >::True;
};
最后一个专门化旨在覆盖其他专门化,但我收到IsOneOf<any_of<int>,any_of<int,double,float>>::True
的模糊实例化错误。有人可以建议一种方法来克服这个问题吗
答案 0 :(得分:1)
最后一项专业化IsOneOf<any_of<T1,Ts1...>, any_of<Ts2...>>
并不比IsOneOf<T,any_of<T2,Ts...>>
更专业化,因为如果Ts2
是一个空列表,则它不能与后者匹配。我想你想要这个,或者代替你上一次的专业化,或者除了你的上一次专业化之外:
template <typename T1, typename ... Ts1, typename T2, typename ... Ts2>
struct IsOneOf< any_of<T1,Ts1 ...>, any_of<T2,Ts2 ...> >
{
const static bool True = IsOneOf<T1, any_of<T2,Ts2...>>::True &&
IsOneOf<any_of<Ts1...>, anyOf<T2,Ts2...>>::True;
};
IsOneOf<any_of<int,double>, any_of<int,double>>
也会遇到问题,因为在这种情况下,IsOneOf<T,T>
与此一般情况不明确。所以你可以通过指定交集来剪掉它:
template <typename T1, typename ... Ts>
struct IsOneOf< any_of<T1,Ts ...>, any_of<T1,Ts ...> >
{
const static bool True = true;
};
如果您还没有any_of<>
,那么您还需要处理{{1}}类型的基本案例。
答案 1 :(得分:0)
这个复杂而不透明的设计的重点是什么?如果IsOneOf<A,B...>::value
是true
的想法当且仅当B
类型中的至少一个与A
相同时,那么一个简单的递归设计(避免辅助设备等)如any_of
),例如
// is_one_of<A,B1,B2,...>::value == is_same<A,B1>::value || is_same<A,B2>::value ...
template<typename A, typename... B>
struct is_one_of;
// case of empty pack B...
template<typename A>
struct is_one_of<A> : std::false_type {};
// general case: recurse
template<typename A, typename B1, typename... B>
struct is_one_of<A,B1,B...>
: std::integral_constant<bool, std::is_same<A,B1>::value || is_one_of<A,B...>::value> {};
是首选的,只需要两个特化(对于B
的空包和递归情况)。此外,is_one_of
来自std::integral_constant<bool,C>
,是优秀的C ++公民。