将trait类模板用作模板参数
template<typename T>
struct SumFixedTraits;
template<>
struct SumFixedTraits<char>
{
using sumT = int;
static sumT initValue() {
return 0;
}
};
template<>
struct SumFixedTraits<int>
{
using sumT = __int64;
static sumT initValue() {
return 0;
}
};
template<>
struct SumFixedTraits<double>
{
using sumT = double;
static sumT initValue() {
return 0.0;
}
};
template<typename T>
auto funcsum(const T* begin, const T* end)
{
using sumT = typename SumFixedTraits<T>::sumT;
sumT sum = SumFixedTraits<T>::initValue();
for (;;)
{
sum += (*begin);
if (begin == end)
break;
++begin;
}
return sum;
}
funcsum()
函数模板用于计算数组元素的和值。下面,给funcsum()
函数模板增加一个模板参数以进一步增加funcsum()
函数模板的灵活性。修改后的funcsum()
函数模板代码如下。
template<typename T,typename U = SumFixedTraits<T>>
auto funcsum(const T* begin, const T* end)
{
// using sumT = typename SumFixedTraits<T>::sumT; 本行不需要
// sumT sum = SumFixedTraits<T>::initValue(); 本行不需要
typename U::sumT sum = U::initValue();
for (;;)
{
sum += (*begin);
if (begin == end)
break;
++begin;
}
return sum;
}
在上面的代码中,引入了第2个类型模板参数U,该模板参数有一个默认值,而且这个默认值可以通过第1个模板参数推断出来(第2个模板参数依赖于第1个模板参数),所以一般不需要指定。但如果有特殊的需求,也是可以指定的,这就增加了funcsum()
函数模板使用时的灵活性。
main()主函数
中以往的代码行如下。
char my_char_array[] = "abc";
std::cout << (int)(funcsum(&my_char_array[0], &my_char_array[2])) << std::endl;
上面这两行代码,在调用funcsum()时,第1个类型模板参数T被推断为char类型,第2个类型模板参数U就变成了SumFixedTraits类型。因此,funcsum()函数模板中的代码行:
typename U::sumT sum = U::initValue();
等价于:
typename SumFixedTraits<char>::sumT sum = SumFixedTraits<char>::initValue();
等价于:
int sum = 0;
也就是说,计算和值的时候,用于保存和值的sum变量
是int类型
。如果希望用于保存和值的sum变量
从int类型
变成__int64类型
,怎么做呢?也是可以做到的,这就是引入类型模板参数U
的灵活之处。
将代码行:
std::cout << (int)(funcsum(&my_char_array[0], &my_char_array[2])) << std::endl;
修改为:
std::cout << (int)(funcsum<char, SumFixedTraits<int>>(&my_char_array[0], &my_char_array[2])) << std::endl;
如果需要,还可以把funcsum()
的第2个类型模板参数指定为一个完全不同的trait类模板
,这完全由程序员自己决定。
完整代码,如下:
#include "killCmake.h"
#include<string>
using namespace std;
template<typename T>
struct SumFixedTraits;
template<>
struct SumFixedTraits<char>
{
using sumT = int;
static sumT initValue() {
return 0;
}
};
template<>
struct SumFixedTraits<int>
{
using sumT = __int64;
static sumT initValue() {
return 0;
}
};
template<>
struct SumFixedTraits<double>
{
using sumT = double;
static sumT initValue() {
return 0.0;
}
};
template<typename T,typename U = SumFixedTraits<T>>
auto funcsum(const T* begin, const T* end)
{
// using sumT = typename SumFixedTraits<T>::sumT; 本行不需要
// sumT sum = SumFixedTraits<T>::initValue(); 本行不需要
typename U::sumT sum = U::initValue();
for (;;)
{
sum += (*begin);
if (begin == end)
break;
++begin;
}
return sum;
}
int main()
{
char my_char_array[] = "abc";
std::cout << (int)(funcsum(&my_char_array[0], &my_char_array[2])) << std::endl;
std::cout << (int)(funcsum<char, SumFixedTraits<int>>(&my_char_array[0], &my_char_array[2])) << std::endl;
return 0;
}