已知容器类模板Container及其value_type类型,返回容器类类型Container2,将原value_type按如下规则提升:
template <???> ??? TypePromotion ???; template <class T> using Promotion = ??? TypePromotion ???; template <template <class> class Container, class T> struct ContainerPromotion { using Type = Container<Promotion<T> >; };
注解:
TypePromotion为一个待实现的type_traits设施,负责按照规则提升给定类型。
Promotion为TypePromotion的对外接口。
ContainerPromotion通过Promotion来定义提升后的容器类类型。
其中TypePromotion需要找出给定类型所属的集合,并定义提升后类型。
将类型集合作为模板类型参数包,递归展开该类型包。在递归的每一层判断目标类型T与当前类型U是否相同,递归返回判断结果的累计或。
template <class T> constexpr bool Any() { return false; } template <class T, class U, class... Types> constexpr bool Any() { return std::is_same<T, U>::value || Any<T, Types...>(); }
用std::enable_if_t来启用特定的模板,并通过该模板定义提升后的类型。对于default情况,可以类型集合的补集来实现或降低其重载决策等级。
这里采用函数模板来实现(由于Promotion系列函数模板只出现在decltype表达式中,故不需要定义):
// integer type template <class T> std::enable_if_t<Any<T, bool, short, int, long int, long long int>(), long long int> Promotion(int); // float type template <class T> std::enable_if_t<Any<T, float, double, long double>(), long double> Promotion(int); // default template <class T> T Promotion(...); // sugar template <class T> using type_promotion_t = decltype(Promotion<T>(0));
1 #include <type_traits> 2 3 template <class T> 4 constexpr bool Any() { 5 return false; 6 } 7 8 template <class T, class U, class... Types> 9 constexpr bool Any() { 10 return std::is_same<T, U>::value || Any<T, Types...>(); 11 } 12 13 // integer type 14 template <class T> 15 std::enable_if_t<Any<T, bool, short, int, long int, long long int>(), 16 long long int> Promotion(int); 17 18 // float type 19 template <class T> 20 std::enable_if_t<Any<T, float, double, long double>(), 21 long double> Promotion(int); 22 23 // default 24 template <class T> 25 T Promotion(...); 26 27 // sugar 28 template <class T> 29 using type_promotion_t = decltype(Promotion<T>(0)); 30 31 template <template <class> class Container, class T> 32 struct ContainerPromotion { 33 using Type = Container<type_promotion_t<T> >; 34 }; 35 36 // Container class template for testing 37 template <class T> 38 class Vector {}; 39 40 int main() { 41 using Type1 = typename ContainerPromotion<Vector, int *>::Type; 42 static_assert(std::is_same<Type1, Vector<int *> >::value, ""); 43 44 using Type2 = typename ContainerPromotion<Vector, short>::Type; 45 static_assert(std::is_same<Type2, Vector<long long int> >::value, ""); 46 47 using Type3 = typename ContainerPromotion<Vector, float>::Type; 48 static_assert(std::is_same<Type3, Vector<long double> >::value, ""); 49 50 return 0; 51 }
-
C++14 SFINAE 容器类value_type类型提升
原文:http://www.cnblogs.com/activa/p/6361465.html