《GeekBand》STL与泛型编程03

本文通过具体实例介绍如何在泛型编程中利用特性解决不同类型数值处理的问题,并展示了如何通过特性避免溢出。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这篇博客还是以本周作业为主,说一下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;
}


这个模板函数看起来是没什么毛病的,但是仔细想一下,如果我们用char型来调用模板函数时,会发生什么?比如计算“hello world”,total溢出了,因为char最大值是255。


这个时候我们就可以用特性来解决。


这个时候 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;
}

我的理解是可能函数模板也可以特化?暂时还没查到相关资料。


以上。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值