首页 > 编程语言 > 详细

C++14 SFINAE 容器类value_type类型提升

时间:2017-02-02 19:11:25      阅读:371      评论:0      收藏:0      [点我收藏+]

C++14 SFINAE 容器类value_type类型提升

原问题:

已知容器类模板Container及其value_type类型,返回容器类类型Container2,将原value_type按如下规则提升:

  • boolshort intintlong intlong long int,提升为long long int
  • floatdoublelong double,提升为long double
  • default,保持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设施,负责按照规则提升给定类型。

PromotionTypePromotion的对外接口。

ContainerPromotion通过Promotion来定义提升后的容器类类型。

其中TypePromotion需要找出给定类型所属的集合,并定义提升后类型。

如何判断给定类型T是否属于某个类型的集合?

将类型集合作为模板类型参数包,递归展开该类型包。在递归的每一层判断目标类型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 }

FAQ:

C++14 SFINAE 容器类value_type类型提升

原文:http://www.cnblogs.com/activa/p/6361465.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!