zoukankan      html  css  js  c++  java
  • 泛型编程之特性(traits)

      特性(traits):对于某种可能会出错的返回值型别(Return Type),利用类模版进行部分特例化。其思想类似设计模式。  

      我们只能部分特例化类模板,而不能部分特例化函数模版。——《C++ Primer(5th)》 P628

    part 1. 实现 Sigma 函数

      功能:将一段范围内的元素求累加和。

      1. 错误的代码实例:

    template <typename T>
    T sigma(T* start, T* end)
    {    
        T total = T();
        while (start != end)
            total += *start++;
        return total;
    }

      1.1 错误原因:

      如果传入 char 类型范围(迭代器)“a b c”,理论上计算结果应该返回 294 ,也就是 0x0126 ,存储需要两个字节。但是 char 只有一个字节大小,所以会造成溢出。

      实际输出结果为 38 ——也就是溢出之后的值。

      2. 正确的代码,采用偏特化,针对不同的型别写出不同的对策——本例中“对策”是声明不同的内置型别来存储返回值类型。

    template <typename T> class  SigmaTraits {};
    
    template<>
    class SigmaTraits <char> // 针对char型的对策
    {
        public: typedef int returnType;
    };
    
    template<>
    class SigmaTraits <int> // 针对int型的对策
    {
        public: typedef int returnType; 
    };
    
    template <typename T>
    typename SigmaTraits<T>::returnType sigma(T* start, T* end)
    {
        typedef typename SigmaTraits<T>::returnType returnType;
        returnType total = returnType();
        while (start != end)
        {
            total += *start++;
        }
        return total;
    }

      3. 调用 sigma 函数的方法方式都是一样的。

      3.1 char范围的调用实例:

    char str[] = "abc";
    cout << sigma(str, str + 3) << endl;

      3.2 int范围的调用实例:

    int arr[] = {1, 2, 3};
    cout << sigma(arr, arr+3) << endl;

       4. 总结

      理解 traits 更像像是一种设计模式,类似于工厂方法:针对不同的型别,有不同的对策。

      模版类 SigmaTraits 叫做 traits template,它含有其参数型别 T 的一个特性(trait),即 ReturnType。

     

  • 相关阅读:
    线段树套线段树
    hdu6800
    半平面交 poj1279
    Unity:创建了一个自定义的找子物体的脚本
    Unity:一个简单的开门动画
    hdu 4940
    hdu 4939
    hdu 4932
    hdu 4912
    AC自动机
  • 原文地址:https://www.cnblogs.com/fengyubo/p/4858739.html
Copyright © 2011-2022 走看看