一、使用 t r a i t trait trait类模板完善函数模板
之前在【萃取技术】萃取技术中的值萃取 这篇文章使用萃取技术实现了 f u n c s u m funcsum funcsum函数模板,用于求一段区间内的和,但是每次的返回值都比较固定。
现在,我们将 t r a i t trait trait类模板用作参数传入函数模板,这样就可以指定返回值类型了。
回顾一下之前的代码:
//使用萃取技术来简化模板
//泛化版本
template<typename T>
struct SumFixedTraits; //只需要声明
//char类型特化版本
template<>
struct SumFixedTraits<char> {
using sumT = int;
};
//int类型特化版本
template<>
struct SumFixedTraits<int> {
using sumT = long long;
};
//float类型特化版本
template<>
struct SumFixedTraits<float> {
using sumT = double;
};
//改造后的funcsum
//使用别名模板
template<typename T>
using sumT = typename SumFixedTraits<T>::sumT;
template<typename T>
sumT<T> funcsum2(const T* begin, const T* end) {
sumT<T> sum{};
for (;;) {
sum += (*begin);
if (begin == end) {
break;
}
++begin;
}
return sum;
}
我们这里默认
c
h
a
r
char
char类型返回
i
n
t
int
int类型,如果我们想要让
c
h
a
r
char
char类型的求和返回KaTeX parse error: Expected group after '_' at position 1: _̲_int64类型呢? 实际上,我们可以对该求和函数模板进行改造,传入指定的SumFixedTarit
类模板,这样就能指定返回值类型了。
参考以下代码:
template<typename T>
struct SumFixedTraits;
template<>
struct SumFixedTraits<int> {
using sumT = __int64;
static sumT initValue() { return 0; }
};
template<>
struct SumFixedTraits<char> {
using sumT = __int32;
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) {
typename U::sumT sum = U::initValue();
for (auto it = begin; it != end; ++it) {
sum += *it;
}
return sum;
}
观察改变的代码部分,除了将静态变量变为静态函数之外,就修改了求和函数的传参部分,如下:
下面是测试代码,可以指定返回值类型:
void Test1() {
//指定使用__int64类型的返回值
char arr1[] = "abc";
auto res1 = funcsum<char, SumFixedTraits<int>>(arr1, arr1 + 3);
std::cout << "类型为:" << typeid(decltype(res1)).name() << ",大小为:" << res1 << std::endl;
//默认__int64类型的返回值
int arr2[] = { 1,2,3 };
auto res2 = funcsum(arr2, arr2 + 3);
std::cout << "类型为:" << typeid(decltype(res2)).name() << ",大小为:" << res2 << std::endl;
//默认double类型的返回值
double arr3[] = { 1.0,2.0,3.0 };
auto res3 = funcsum<double, SumFixedTraits<double>>(arr3, arr3 + 3);
std::cout << "类型为:" << typeid(decltype(res3)).name() << ",大小为:" << res3 << std::endl;
}
运行结果如下: