(C++模板编程):萃取技术及fixed traits(固定萃取)

萃取技术及fixed traits(固定萃取)

【基本概念】

  • trait(萃取)技术用于对模板中的各种模板参数进行管理
  • type traits:类型萃取
  • fixed traits(固定萃取):主要用于给进来一种类型,萃取出(得到)另外一种类型。

【目标】

  • (a)了解标准库中许多trait技术的实现方法。
  • (b)灵活运用并组合这些实现方法,写出功能跟强大,更优雅和实用的代码。

【引例】

//计算数组中元素的和值的函数模板
template <typename T>
T funcsum(const T* begin, const T* end)
{
	T sum{}; 
	//零初始化,如果数值型变量被初始化为0,指针型变量被初始化为nullptr,bool类型变量被初始化为false。
	for (;;)
	{
		sum += (*begin);
		if (begin == end)
			break;
		++begin;
	}
	return sum;
}
  • 调用
int myintarray1[] = { 10,15,20 };
int myintarray2[] = { 1000000000,1500000000,2000000000 }; //10亿,15亿,20亿
char mychararray[] = "abc";//97,98,99

cout << funcsum(&myintarray1[0], &myintarray1[2]) << endl;  //int funcsum<int>(const int*,const int*);
cout << funcsum(&myintarray2[0], &myintarray2[2]) << endl;
cout << (int)(funcsum(&mychararray[0], &mychararray[2])) << endl; //char funcsum<char>(const char*,const char*);
  • 输出

  • 由于超出返回类型的能表示的最大范围,第二,三个结果发生溢出问题。

【改进版】

  • 指定返回类型
template <typename U,typename T>
U funcsum(const T* begin, const T* end)
{
	U sum{};
	for (;;)
	{
		sum += (*begin);
		if (begin == end)
			break;
		++begin;
	}
	return sum;
}
  • 调用
int myintarray1[] = { 10,15,20 };
int myintarray2[] = { 1000000000,1500000000,2000000000 }; //10亿,15亿,20亿
char mychararray[] = "abc";//97,98,99

//int64_t,long long 
cout << funcsum<__int64>(&myintarray1[0], &myintarray1[2]) << endl;  //int funcsum<int>(const int*,const int*);
cout << funcsum<__int64>(&myintarray2[0], &myintarray2[2]) << endl;
cout << (int)(funcsum<int>(&mychararray[0], &mychararray[2])) << endl; //char funcsum<char>(const char*,const char*);
  • 输出

【fixed traits(固定萃取)方案】

  • SumFixedTraits固定萃取类模板的作用:通过类型,得到另外一个类型
//fixed traits类模板的泛化版本
template<typename T>
struct SumFixedTraits; //不需要实现代码,因为不需要用该版本进行实例化。

//各个fixed traits类模板的特化版本
//(1)给进来char类型时,返回的是int类型
template <>
struct SumFixedTraits<char> //char表示给进来的是char类型
{
	using sumT = int; //类型别名sumT代表int类型(返回类型)
};
//(2)给进来int类型时,返回的是__int64(long long/int64_t)类型
template <>
struct SumFixedTraits<int> //int表示给进来的是int类型
{
	using sumT = __int64; //类型别名sumT代表__int64类型(返回类型)
};
//(3)....其他给进来的是某个类型,返回的是另外一个类型,可以任意扩展出多个SumFixedTraits类模板的特化版本。

//-----------------------
template <typename T>
auto funcsum(const T* begin, const T* end)
{
	using sumT = typename SumFixedTraits<T>::sumT; //给进来一个类型(T),返回一个类型(sumT),这是fixed traits的运用。
	sumT  sum{}; 
	for (;;)
	{
		sum += (*begin);
		if (begin == end)
			break;
		++begin;
	}
	return sum;
}
  • 调用
int myintarray1[] = { 10,15,20 };
int myintarray2[] = { 1000000000,1500000000,2000000000 }; //10亿,15亿,20亿
char mychararray[] = "abc";//97,98,99

cout << funcsum(&myintarray1[0], &myintarray1[2]) << endl;  //int funcsum<int>(const int*,const int*);
cout << funcsum(&myintarray2[0], &myintarray2[2]) << endl;
cout << (int)(funcsum(&mychararray[0], &mychararray[2])) << endl; //char funcsum<char>(const char*,const char*);
  • 输出

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值