课程咨询 : 020-87532245 24小时热线:15622781509 咨询QQ:3061057839

广州C++培训 > 达内新闻 > C++14 SFINAE容器类value_type类型提升
  • C++14 SFINAE容器类value_type类型提升

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

  • 广州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++--零基础周末班

开班日期:4月15日

c++--零基础全日制班

c++--零基础全日制班

开班日期:4月15日

c++--免费训练营

c++--免费训练营

开班日期:4月15日

c++--高薪就业班

c++--高薪就业班

开班日期:4月15日

  • 网址:http://gz.c.tedu.cn     地址:广州市天河北五山路 141 号尚德大厦 627
  • 课程培训电话: 020-87532245 24小时热线:15622781509 咨询QQ:3061057839     全国服务监督电话:400-827-0010
  • 服务邮箱 ts@tedu.cn
  • 2001-2016 达内时代科技集团有限公司 版权所有 京ICP证8000853号-56