• 【C++】Geekband-专题四:traints的使用


    1. 基本定义

    • Think of a trait as a small object whose main purpose is to carry information used by another object or algorithm to determine “policy” or “implementation details”.
    • In some cases the extra parameters are entirely determined by a few main paameters. 因此需要通过几个核心参数型别的定义,来设计不同的模板,满足不同需求。

    2. Fixed Traits

    • 主要是构造适应各种类型的函数
    • Fixed主要指,一旦T在模板中被定义,则无法再调用中改变。

    2.1 传统方法

    • 传统方法定义的模板
    1. #ifndef ACCUM_HPP
    2. #define ACCUM_HPP
    3. template <typename T>
    4. inline
    5. T accum (T const* beg, T const* end)
    6. {
    7. T total = T(); // assume T() actually creates a zero value
    8. while (beg != end) {
    9. total += *beg;
    10. ++beg;
    11. }
    12. return total;
    13. }
    14. #endif // ACCUM_HPP
    • 调用该模板
    1. #include "accum1.hpp"
    2. #include <iostream>
    3. int main()
    4. {
    5. // create array of 5 integer values
    6. int num[]={1,2,3,4,5};
    7. // print average value
    8. std::cout << "the average value of the integer values is "
    9. << accum(&num[0], &num[5]) / 5
    10. << ' ';
    11. // create array of character values
    12. char name[] = "templates";
    13. int length = sizeof(name)-1;
    14. // (try to) print average character value
    15. std::cout << "the average value of the characters in ""
    16. << name << "" is "
    17. << accum(&name[0], &name[length]) / length
    18. << ' ';
    19. }
    • 存在问题,当调用的是char时,模板自动将返回函数也定义为char,而不是期望的int

      2.2 使用Traits方法

    • 模板定义

    1. template<typename T>
    2. class AccumulationTraits;
    3. template<>
    4. class AccumulationTraits<char> {
    5. public:
    6. typedef int AccT;
    7. };
    8. template<>
    9. class AccumulationTraits<short> {
    10. public:
    11. typedef int AccT;
    12. };
    13. template<>
    14. class AccumulationTraits<int> {
    15. public:
    16. typedef long AccT;
    17. };
    18. template<>
    19. class AccumulationTraits<unsigned int> {
    20. public:
    21. typedef unsigned long AccT;
    22. };
    23. template<>
    24. class AccumulationTraits<float> {
    25. public:
    26. typedef double AccT;
    27. };
    28. template <typename T>
    29. inline
    30. typename AccumulationTraits<T>::AccT accum (T const* beg,
    31. T const* end)
    32. {
    33. // return type is traits of the element type
    34. typedef typename AccumulationTraits<T>::AccT AccT;
    35. AccT total = AccT(); // assume T() actually creates a zero value
    36. while (beg != end) {
    37. total += *beg;
    38. ++beg;
    39. }
    40. return total;
    41. }
    • 调用方法不变。

    2.3 总结

    160422.C Program.png

    3. Value Traits

    • 对模板中特定数值,特别是初始话时候的操作方法
    • 模板的书写,引入zero()
    1. template<typename T>
    2. class AccumulationTraits;
    3. template<>
    4. class AccumulationTraits<char> {
    5. public:
    6. typedef int AccT;
    7. static AccT zero() {
    8. return 0;
    9. }
    10. };
    11. template<>
    12. class AccumulationTraits<short> {
    13. public:
    14. typedef int AccT;
    15. static AccT zero() {
    16. return 0;
    17. }
    18. };
    19. template<>
    20. class AccumulationTraits<int> {
    21. public:
    22. typedef long AccT;
    23. static AccT zero() {
    24. return 0;
    25. }
    26. };
    27. template<>
    28. class AccumulationTraits<unsigned int> {
    29. public:
    30. typedef unsigned long AccT;
    31. static AccT zero() {
    32. return 0;
    33. }
    34. };
    35. template<>
    36. class AccumulationTraits<float> {
    37. public:
    38. typedef double AccT;
    39. static AccT zero() {
    40. return 0;
    41. }
    42. };
    43. template <typename T>
    44. inline
    45. typename AccumulationTraits<T>::AccT accum (T const* beg,
    46. T const* end)
    47. {
    48. // return type is traits of the element type
    49. typedef typename AccumulationTraits<T>::AccT AccT;
    50. AccT total = AccumulationTraits<T>::zero();
    51. while (beg != end) {
    52. total += *beg;
    53. ++beg;
    54. }
    55. return total;
    56. }
    • 调用方法不变
    • 总结
      160422.C Program.png

    4. Parameterized Traits

    • 为了增加灵活性,引入另一个参数(AT),使其来决定参数(T)的类型。
    • 有两种方法,一种是基于function traits的方法
    1. template <typename T>
    2. inline
    3. typename AccumulationTraits<T>::AccT accum (T const* beg,
    4. T const* end)
    5. {
    6. return Accum<T>::accum(beg, end);
    7. }
    8. template <typename Traits, typename T>
    9. inline
    10. typename Traits::AccT accum (T const* beg, T const* end)
    11. {
    12. return Accum<T, Traits>::accum(beg, end);
    13. }
    • 另一种是将function traits方法引入Class
    1. template <typename T,
    2. typename AT = AccumulationTraits<T> >
    3. class Accum {
    4. public:
    5. static typename AT::AccT accum (T const* beg, T const* end)
    6. {
    7. typename AT::AccT total = AT::zero();
    8. while (beg != end) {
    9. total += *beg;
    10. ++beg;
    11. }
    12. return total;
    13. }
    14. };
    • 总结
      160422.C Program.png

    Reference

  • 相关阅读:
    谈谈java default关键字的妙用 AlanTuring
    tomcat启动项目控制台乱码问题解决 AlanTuring
    针对前端数据量大缓存问题,后端设计接口解决的方案分析 AlanTuring
    post接口入参同时包含param跟body AlanTuring
    mybatis plus实现使用聚合函数,group by分组
    MyBatisPlus主键ID生成策略
    关于Git和Svn的区别
    Lock和synchronized
    炒股经验教训
    Mybatis Doc Java API
  • 原文地址:https://www.cnblogs.com/kongww/p/5425373.html
Copyright © 2020-2023  润新知