模版特例化(traits)

  Traits偏特化:类模板部分特例化(partial specialization)

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

  1. 实现 Sigma 函数,功能是将一段范围内的元素求累加和。

  2. 错误的代码实例:

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

  2.1 错误原因:

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

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

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

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;
}

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

  4.1 char范围的调用实例:

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

  4.2 int范围的调用实例:

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

  5. 总结

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

 

时间: 2024-10-11 04:18:12

模版特例化(traits)的相关文章

类模板特例化

参考来源:C++ primer 中文版第5版 P626. 1.举个例子:为标准库hash模板定义一个特例化版本,可以用它来将Sales_data对象保存在无序容器中. 默认情况下,无序容器使用hash<key_type>来组织元素. 为了让我们自己的数据类型也能使用这种默认组织方式吗,必须定义hash模板的一个特例化模板. 一个特例化hash类必须定义: (1) 一个重载的调用运算符,它接受一个容器关键字类型的对象,返回一个size_t. (2)两个类型成员,result_type和argum

php模版静态化技术

PHP页面的静态化很有必要,尤其是在CMS系统中,一些内容一旦生成,基本上不会有变化,这时如果用html将页面静态化,无疑会减少服务其解析PHP页面的负担.以下是看书学来的PHP静态化技术,记录之以备不时之需. 无论是利用框架还是简单的脚本,原理基本一致:就是利用PHP进行文件操作,替换html模板中的动态元素. 简单的例子: 1.建立模板(template.html) <html>   <head>      <title>一篇文章</title>   &

模版结构化优化-include引入模版

前提:为什么需要引入模版? 例如:在网页中可能只是局部在发生变化,头部和尾部都是固定不变的,那么局部在变化的时候,切换了地址,也就是切换到了另外一个页面 这样的话只有局部代码发生了改变,头部和尾部的代码都是不变的,在复制头部和尾部的相同代码给其他子页面的话就不是一个很好的办法了 所以,就是用到了引入模版 第一步:先创建django的脚手架 第二步:在templates下创建3个测试的页面  第三步:在view.py中渲染页面 第四步:在urls.py中做映射 第五步: 给这三个页面简单做个样式

模板特例化

template <typename T> class A{ private: T a; public: A(T x) :a(x){} void display() { cout << a << endl; } }; template<> class A<double> { private: double a; public: A(double x) :a(x){} void display() { cout << a <<

php模版静态化原理

看了一些开源系统的,简单的总结一下php的模板及静态原理. 先贴代码,再做解释. index.php Php代码   <?php //如果已存在静态页面,直接读取并显示 if(file_exists('index.html')) { echo file_get_contents('index.html'); } else { //这里把需要的变量都附好值 $var = "Hello,World."; //开启输出缓存 ob_start(); //这里调用模板,模板里嵌入一些PHP

泛型编程深入探索之二,模板递归与可变参数模版

以构建一个n纬网格为例,讲述模板递归. 首先是一个简单的一纬网格的实现,这个网格实现了规定长度的网格的实例化,并且能够在不同大小的网格类中自由的转型(通过模版嵌套的cast_ctr) (使用到的技术,非类型参数模版,模版嵌套,类模版特例化,模版友元函数) #include <cassert> #include <iostream> using namespace std; template <typename T,int LENGTH> class grid; temp

转:C++ Boost/tr1 Regex(正则表达式)快速指南

C++ Boost/tr1 Regex(正则表达式)快速指南 正则表达式自Boost 1.18推出,目前已经成为C++11(tr1)的标准部分. 本文以Boost 1.39正则表达式为基础,应该广泛适用于其他版本的Boost.对namespace稍加修改,即可适用tr1标准. 0.regex对象 类似于Java中的Pattern,Boost中的正则表达式对象为: boost::regex 常见构造方法2种: 1 2 3 4 5 // 1. 直接使用正则表达式的字符串构造. boost::rege

C++——模板

1.参数类型 template <typename T> void f1(T&);//实参必须是左值 f1(i);//对 f1(ci);//对,T的类型是const int f1(5);//错 template <typename T> void f2(const T&);//实参可以是左值,const右值 f2(i);//对 f2(ci);//对 f2(5);//对 template <typename T> void f3(T&&);

条款47:请使用traits class表示类型信息

在stl的算法中,我们的希望往往是根据不同的迭代器类型进行不同的更有效率的操作: 1 template<typename IterT, typename DistT> 2 void advance(IterT iter, DistT dis) 3 { 4 if(iter is a random access iterator) 5 iter += dis; 6 else{ 7 if(dis >= 0){ 8 while(dis--) 9 iter++; 10 }else{ 11 whil