fixed trait

要求:编写一个能适合许多类型的模板来完成一个累加操作

解答1:

//定义一个模板函数
#ifndef ACCUM_H
#define ACCUM_H
template<typename T>
inline
T accum(T const* beg,T const* end)
{
    T total=T();//假设T()事实上会产生一个等于0的值
    while(beg != end)
    {
        total += *beg;
        ++beg;
    }
    return total;
}
#endif

 


解析:上面的代码,有两个问题:
(1)如何正确生成一个0值,以便开展我们的求和过程。
(2)如何确保T类型相加的和不会溢出。
比如:
我们在下面的源文件中调用上述代码:

#include"accum0.h"
#include<iostream>

int main()
{
    int num[] = {1,2,3,4,5};
    char name[] = "templates";
    int length = sizeof(name)-1;

    std::cout << "The average value of the integer values is :"
        << accum(&num[0],&num[5])/5 << std::endl;

    std::cout << "The average value of the characters in \" "
        << name << "\" is: "
        << accum(&name[0],&name[length])/length
        << std::endl;
    return 0;
}

 


代码产生的结果为:
The average value of the integer values is :3
The average value of the characters in “templates” is :-5

我们发现当我们使用字符char类型的时候,就发生了求和溢出的现象。
显然,我们可以通过引入一个额外的模板参数AccT来解决这个问题,其中
AccT描述了变量total的类型,然而这样会给该模板的使用者都强加了一个
额外的负担,他们每次在调用这个模板的时候,都要指定这个额外的类型,
我们每次不得不这样来写:
accum<int>(&nume[0],&name[length])
虽说这个约束不是很麻烦,但是我们仍然希望避免这个约束。

此时,我们引入trait模板,其中定义的是和类型T的一些关联特征。

//accumtraits2.h
template<typename T>
class AccumulationTraits;

template<>
class AccumulationTraits<char>{
public:
    typedef int AccT;
};

template<>
class AccumulationTraits<short>{
public:
    typedef int AccT;
};

template<>
class AccumulationTraits<int>{
public:
    typedef long AccT;
};

template<>
class AccumulationTraits<unsigned int>{
public:
    typedef unsigned long AccT;
};

template<>
class AccumulationTraits<float>{
public:
    typedef double AccT;
};

 


在上面的代码中,模板AccumulationTraits被称为一个trait模板,因为
它含有它的参数类型的一个trait。
现在,我们可以改写前面写的accum()模板了:

//accum2.h
#ifndef ACCUM_H
#define ACCUM_H

#include "accumtraits2.h"
template<typename T>
inline
typename AccumulationTraits<T>::AccT accum(T const* beg,T const* end)
{
    typedef AccumulationTraits<T>::AccT AccT;
    AccT total = AccT();
    while(beg != end)
    {
        total += *beg;
        ++beg;
    }
    return total;
}
#endif

 


现在我们运行前面的程序,就会出现我们期望的结果:
The average value of the integer values is :3
The average value of the characters in “templates” is :108

posted @ 2011-11-02 00:29  MagiCube  阅读(284)  评论(0编辑  收藏  举报