广州C/C++培训
达内广州岗顶中心

18087159764

热门课程

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

  • 时间:2017-02-06
  • 发布:广州C++培训
  • 来源:博客园

广州C++培训班的小编这一期给大家讲C++14 SFINAE容器类value_type类型提升。

原问题:

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

bool,short int,int,long int,long long int,提升为long long int

float,double,long 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设施,负责按照规则提升给定类型。

Promotion为TypePromotion的对外接口。

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 }

了解详情请登陆广州达内C++培训官网(gz.c.tedu.cn)!

上一篇:C++的线性规划
下一篇:【广州达内C++培训】c++之五谷杂粮

达内广州编程班:揭开指纹识别技术面纱

达内广州c++班:一篇文章看透指纹识别

达内广州c语言班:来自老程序员的感悟

达内广州c语言班:华为要能超越苹果市场吗?

选择城市和中心
贵州省

广西省

海南省