【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. << '\n';
  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. << '\n';
  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

posted @ 2016-04-23 19:42  Frankww  阅读(501)  评论(0编辑  收藏  举报