这篇博客还是以本周作业为主,说一下Generic Programming中应用比较广的Traits(特性);
先看一下题目:
假设有个计算类Calculator,它要处理int, long, float, double等数值类型。用模板实现GetLimit()方法,获得每种类型的数值的上限LIMIT,比如int的上限是100,long的上限是 1000,float的上限是999.99,double的上限是888.8888888等等。
这个题目乍一看让人觉得不知所云,但是结合这一课程的题目,能猜得到是希望使用泛型编程中的模板来解决这个问题。
为什么使用特性,这里引入ppt中的例子,这个例子还是十分恰当的:
假设给定一个数组,希望计算数组中所有元素的值,那么用类模板很容易实现:
template <typename T> T Sigma(const T* start,const T* end)
{
<span style="white-space:pre"> </span>T total =T(); //suppost T()actually creates a zero vale
<span style="white-space:pre"> </span>while(strat != ent){
<span style="white-space:pre"> </span>total += *start++;
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>return total;
}
这个时候我们就可以用特性来解决。
这个时候 sigma就可以改写为:
template <typename T>
typename SigmaTraits<T>::ReturnType sigma(const T* start, const T*end)
{
<span style="white-space:pre"> </span>typedef typename SigmaTraits<T>::ReturnType ReturnType;
<span style="white-space:pre"> </span>ReturnType s = ReturnType();
<span style="white-space:pre"> </span>while(strat !=end)
<span style="white-space:pre"> </span>s += *start++;
<span style="white-space:pre"> </span>return s;
}
这个时候再调用就不会发生溢出。
那么在这个基础上,作业题目实现就比较容易了:
#include<iostream>
using namespace std;
template <typename T>
class CalculatorTraits{};
template <>
class CalculatorTraits<int>
{
public:
typedef int ReturnType;
static ReturnType LIMIT;
};
CalculatorTraits<int>::ReturnType CalculatorTraits<int>::LIMIT = 100;
template <>
class CalculatorTraits<long>
{
public:
typedef long ReturnType;
static ReturnType LIMIT;
};
CalculatorTraits<long>::ReturnType CalculatorTraits<long>::LIMIT = 1000;
template <>
class CalculatorTraits<float>
{
public:
typedef float ReturnType;
static ReturnType LIMIT;
};
CalculatorTraits<float>::ReturnType CalculatorTraits<float>::LIMIT = 999.99;
template <>
class CalculatorTraits<double>
{
public:
typedef double ReturnType;
static ReturnType LIMIT;
};
CalculatorTraits<double>::ReturnType CalculatorTraits<double>::LIMIT = 888.8888888;
template <typename T>
class Calculator
{
public:
typename CalculatorTraits<T>::ReturnType GetLimit(){
return CalculatorTraits<T>::LIMIT;
}
};
int main()
{
<span style="white-space:pre"> </span>Calculator<int> cal1;
Calculator<long> cal2;
Calculator<float> cal3;
Calculator<double> cal4;
cout << cal1.GetLimit() << endl;
cout << cal2.GetLimit() << endl;
cout << cal3.GetLimit() << endl;
cout << cal4.GetLimit() << endl;
return 0;
}
当然,特性的用法不仅如此,还需要继续去学习。
在查询资料过程中,发现一个比较简单的实现方式,应该是GeekBand的一个学长?做的
#include <iostream>
using namespace std;
struct Calculator {
template<typename T> T GetLimit() const { return T(65); }
};
template<> int Calculator::GetLimit() const { return int(100); }
template<> long Calculator::GetLimit() const { return long(1000); }
template<> float Calculator::GetLimit() const { return float(999.99); }
template<> double Calculator::GetLimit() const { return double(888.8888888); }
int main() {
Calculator ca;
cout << "Limit of int : " << ca.GetLimit<int>() << endl;
cout << "Limit of long : " << ca.GetLimit<long>() << endl;
cout << "Limit of float : " << ca.GetLimit<float>() << endl;
cout << "Limit of double : " << ca.GetLimit<double>() << endl;
cout << "Limit of char : " << ca.GetLimit<char>() << endl;
return 0;
}
我的理解是可能函数模板也可以特化?暂时还没查到相关资料。
以上。