本文参考文献::GeekBand课堂内容,授课老师:张文杰

    :C++ Templates  15章节

:网络资料: http://blog.csdn.net/my_business/article/details/7891687

1、定义:

  函数,类或者一些封装的通用算法中的某些部分会因为数据类型不同而导致处理或逻辑不同(而我们又不希望因为数据类型的差异而修改算法本身的封装时)。traits会是一种很好的解决方案。

助教提示:

1、不要像用switch一样枚举各个类型,用traits用模板实现。

2、第一是希望会使用traits表达类型信息,因为C++没有C#/Java中类似类型的判断,比如C#里有if (type is SomeType) { … },但C++没有。这个时候考虑用traits表达;第二,希望注意类似typename CalculatorTraits<T>::ReturnType的返回类型,不要觉得奇怪,是模板中常用的。

2、举例分析:

根据上面的提示,查阅了C++ Templates,进行如下的分析:

例一:(C++ Templates Page 240)

第一部分输出5个整数的平均值

第二部分输出字符的平均值

#include"accum1.h"
#include<iostream> int main()
{
int num[] = {,,,,};
//
cout<<"The average value of integer valus us"
<< accum(&num[],&num[])/; char name[] = " templates "
int length = sizeof(name) -; //
cout<<"the average value of the characters in \"
<<name <<'\n' is"
<<accum(&name[],&name[length])/length
<<'\n' ; }

由于我们是基于char类型进行实例化的,char类型范围很小,很容易出现越界的现象。所以我们要为该模板的所有用户创建而外的类型。

如下述,要使用这种方法才可以。

accum<int> (&name[],&name[length])

所有的正常点的用户都会抱怨这样的封装,因为用户不理解为什么要让他们去关心自己的模板类型是否越界,用户不明白为什么要自己定义输出类型呢?也不明白如何确定输出类型?

举例二:

 
template <typename T>
class Test {
......
};

Test中的某部分处理会随着类型T的不同而会有所不同,比如希望判断T是否为指针类型,当T为指针类型时的处理有别于非指针类型,怎么做?模板里再加个参数

template <typename T, bool isPointer>
class Test {
......// can use isPointer to judge whether T is a pointer
};

所有的正常点的用户都会抱怨这样的封装,因为用户不理解为什么要让他们去关心自己的模板类型是否为指针,既然是Test类本身的逻辑,为什么麻烦用户呢?

三、分析

解决的方法就是——使用每个模板的特化来写出这些关联代码

如习题中假设有个计算类Calculator,它要处理int, long, float, double等数值类型。

用模板实现GetLimit()方法,获得每种类型的数值的上限LIMIT,

比如int的上限是100,long的上限是 1000,float的上限是999.99,double的上限是888.8888888等等。

如果采用通用模板T,则不会因为输入类型不同而返回不同值。

template <typename T>
struct Calculator
{
public:
typename CalculatorHelper<T>::ret_type GetLimit()
{
return CalculatorHelper<T>::LIMIT;
};
private:
T mDate;
};

Calculator类中,新建一个结构体 Calculatorhelper 来特化所有出现的可能性。如果采用通用模板T,则不会因为输入类型不同而返回不同值。

#include "stdafx.h"

//普通模板
template <typename T>
struct CalculatorHelper
{ }; //int 特例化,,直接返回LIMIT = 100
template <>
struct CalculatorHelper<int>
{
typedef int ret_type;
static ret_type LIMIT;
}; //long 特例化,直接返回LIMIT = 1000
template <>
struct CalculatorHelper<long>
{
typedef long ret_type;
static ret_type LIMIT;
}; //float 特例化,直接返回LIMIT = 999.99
template <>
struct CalculatorHelper<float>
{
typedef float ret_type;
static ret_type LIMIT;
}; //double 特例化,直接返回LIMIT = 888.8888888
template <>
struct CalculatorHelper<double>
{
typedef double ret_type;
static ret_type LIMIT;
}; CalculatorHelper<int>::ret_type CalculatorHelper<int>::LIMIT = ;
CalculatorHelper<long>::ret_type CalculatorHelper<long>::LIMIT = ;
CalculatorHelper<float>::ret_type CalculatorHelper<float>::LIMIT = 999.99;
CalculatorHelper<double>::ret_type CalculatorHelper<double>::LIMIT = 888.8888888;
int main()
{
//int
Calculator<int> TestInt;
cout << TestInt.GetLimit() << endl; //long
Calculator<long> TestLong;
cout << TestLong.GetLimit() << endl; //float
Calculator<float> TestFloat;
cout << TestFloat.GetLimit() << endl; //double
Calculator<double> TestDouble;
cout.precision();//确保7位显示
cout.setf(ios::fixed);
cout << TestDouble.GetLimit() << endl;
return ; }

通过上述分析:

我们把类型不同的int 、float、double、long,返回值不同。用户不必去关心具体的实现细节。只要输入一个类型的数据,就必然返回一个相应的数值。

总结:

函数,类或者一些封装的通用算法中的某些部分会因为数据类型不同而导致处理或逻辑不同(而我们又不希望因为数据类型的差异而修改算法本身的封装时)。traits会是一种很好的解决方案。

上面仅仅是粗略的理解,还请各位朋友批评指正。

推荐进一步阅读资料:

http://blog.csdn.net/my_business/article/details/8098417

http://blog.csdn.net/zjq2008wd/article/details/41517367

最新文章

  1. 《C#图解教程》读书笔记之二:存储、类型和变量
  2. Nginx + php-fpm 执行 PHP 脚本超时 报错 502 Bad Gateway + 504 Gateway Time-out 的解决办法
  3. background-position 具体的使用说明
  4. CSS菜单横竖布局要点
  5. emulator shortcut
  6. eclipse shortcut binding
  7. 童话故事 --- 什么是SQL Server Browser
  8. 【项目记录】-路灯监测 gmap.net
  9. 为不具有change事件的html标签设置监听事件
  10. KeepAlive--高可用解决方案
  11. 使用quartz数据库锁实现定时任务的分布式部署
  12. eclipse中tomcat可以start启动,无法debug启动的解决
  13. 关闭浏览器时提示的javascript事件
  14. 11-DOM介绍
  15. jquery中ajax的dataType的各种属性含义
  16. ES8新特性——ES8 was Released and here are its Main New Features
  17. log4j配置详解(非常详细)
  18. 【CF938G】Shortest Path Queries(线段树分治,并查集,线性基)
  19. 在Quartus中如何使用TCL脚本文件配制管脚
  20. asp.net 正在加载/处理(兼容IE Chrome)

热门文章

  1. Flask项目之手机端租房网站的实战开发(八)
  2. VC error link
  3. 【例题 7-9 UVA-1601】The Morning after Halloween
  4. Spring学习总结(7)——applicationContext.xml 配置文详解
  5. FZU《C语言程序综合设计》
  6. HibernateCRUD基础框架(1)-实体类
  7. MySQL字符编码问题,Incorrect string value
  8. Linux下的lds链接脚本简介(二)
  9. wepy小程序实现列表分页上拉加载(2)
  10. 结合Wireshark捕获分组深入理解TCP/IP协议栈之TCP协议(TCP报文格式+三次握手实例)