trait与policy模板应用简单示例
accumtraits.hpp // 累加算法模板的trait
// 累加算法模板的trait #ifndef ACCUMTRAITS_HPP #define ACCUMTRAITS_HPP template <typename T> class AccumulationTraits; // 只有声明 template <> class AccumulationTraits<char> // 把具体类型char映射到int,累加后就返回int { public: typedef int AccT; // 统一的类型别名,表示返回类型 static AccT zero() // 关联一个缺省值,是累加时的初始缺省值 { return 0; } }; template <> class AccumulationTraits<short> // 把具体类型short映射到累加后的返回类型int { public: typedef int AccT; static AccT zero() // 没有直接在类内部定义static变量并提供缺省值,而是使用了函数 { // 因为类内部只能对整型和枚举类型的static变量进行初始化 // 其他类型的必须类内部声明,在外部进行初始化 return 0; } }; template <> class AccumulationTraits<int> { public: typedef long AccT; static AccT zero() { return 0; } }; template <> class AccumulationTraits<unsigned int> { public: typedef unsigned long AccT; static AccT zero() { return 0; } }; template <> class AccumulationTraits<float> { public: typedef double AccT; static AccT zero() { return 0; } }; #endif // !ACCUMTRAITS_HPP
policies.hpp // 累加算法模板的policy
// 累加算法模板的policy #ifndef POLICIES_HPP #define POLICIES_HPP template <typename T1, typename T2> class SumPolicy // 累加的策略 { public: static void accumulate(T1 & total, T2 const & value) { total += value; // 累加 } }; template <typename T1, typename T2> class MultPolicy // 累乘的策略 { public: static void accumulate(T1 & total, T2 const & value) { total *= value; // 累乘 } }; #endif // !POLICIES_HPP
accum.hpp // 累加算法模板:实现为类模板,用模板参数来传递policy和trait
// 累加算法模板:实现为类模板,用模板参数来传递policy和trait // 可用一个内联函数模板作为包装器来包装这个类模板实现 #ifndef ACCUM_HPP #define ACCUM_HPP #include "accumtraits.hpp" #include "policies.hpp" #include <iostream> template < typename T, // 这里使用 typename 和 class 没有区别 const int INITVAL = 0, // INITVAL 是一个 无类型模板参数 template <typename, typename> class Policy = SumPolicy, // 这里的必须使用class不能是typename, 因为 Policy 是类类型, 默认采用SumPolicy策略 typename Traits = AccumulationTraits<T> > // 模板参数Traits代表要使用的trait class Accum { public: // AccumulationTraits 是一个 standard traits class (标准特性类) // AccT 嵌套在 AccumulationTraits<T> 内部类型, 而且 T 是一个模版参数 // AccT 是一个 nested dependent type name (嵌套依赖类型名), 必须被 typename 前置 static typename Traits::AccT accum(T const * beg, T const * end) { // total 是一个与 AccT 类型所指向的类型相同的局部变量 // zero() 嵌套在 AccumulationTraits<T> 内部函数, 而且 T 是一个模版参数 //typename Traits::AccT total = Traits::zero(); // 获取缺省值, 返回 0 // 存在问题: 当策略为 MultPolicy 会造成结果始终为 0 typename Traits::AccT total = INITVAL; // 把初始值当作【无类型模板参数】传递进来 while (beg != end) // 作累积运算 { Policy<Traits::AccT, T>::accumulate(total, *beg); // 使用给定的算法策略来进行累积 ++beg; } return total; // 返回累积起来的值 } }; //// 用内联的函数模板来包装, 对默认的参数,提供对应的重载函数 template <typename T, const int INITVAL, template <typename, typename> class Policy, typename Traits> inline typename Traits::AccT accum(T const * beg, T const * end) { std::cout << "<typename T, const int INITVAL, template <typename, typename> class Policy, typename Traits> ---> <T, INITVAL, Policy, Traits>" << std::endl; // 标记使用 return Accum<T, INITVAL, Policy, Traits>::accum(beg, end); } template <typename T, const int INITVAL, template <typename, typename> class Policy> inline typename AccumulationTraits<T>::AccT accum(T const * beg, T const * end) { std::cout << "<typename T, const int INITVAL, template <typename, typename> class Policy> ---> <T, INITVAL, Policy, AccumulationTraits<T>>" << std::endl; // 标记使用 return Accum<T, INITVAL, Policy, AccumulationTraits<T>>::accum(beg, end); } template <typename T, const int INITVAL> inline typename AccumulationTraits<T>::AccT accum(T const * beg, T const * end) { std::cout << "<typename T, const int INITVAL> ---> <T, INITVAL, MultPolicy, AccumulationTraits<T>>" << std::endl; // 标记使用 return Accum<T, INITVAL, MultPolicy, AccumulationTraits<T>>::accum(beg, end); } template <typename T> inline typename AccumulationTraits<T>::AccT accum(T const * beg, T const * end) { std::cout << "<typename T> ---> <T, 1, MultPolicy, AccumulationTraits<T>>" << std::endl; // 标记使用 return Accum<T, 1, MultPolicy, AccumulationTraits<T>>::accum(beg, end); } template <> inline typename AccumulationTraits<int>::AccT accum(int const * beg, int const * end) { std::cout << "<> ---> <int, 1, MultPolicy, AccumulationTraits<int>>" << std::endl; // 标记使用 return Accum<int, 1, MultPolicy, AccumulationTraits<int>>::accum(beg, end); } #endif // !ACCUM_HPP
mytest.cpp // 使用累加算法的客户端测试代码
// 使用累加算法的客户端测试代码 #include "accum.hpp" #include <iostream> int main() { int num[] = {1,2,3,4,5}; // 整型数组 std::cout << "============= integer array =============" << std::endl; std::cout << "the total value of the integer values is " << accum<int, 1, MultPolicy, AccumulationTraits<int>>(&num[0], &num[5]) << std::endl; std::cout << "the total value of the integer values is " << accum<int, 1, MultPolicy>(&num[0], &num[5]) << std::endl; std::cout << "the total value of the integer values is " << accum<int, 1>(&num[0], &num[5]) << std::endl; std::cout << "the total value of the integer values is " << accum<int>(&num[0], &num[5]) << std::endl; std::cout << "the total value of the integer values is " << accum<>(&num[0], &num[5]) << std::endl; std::cout << "the total value of the integer values is " << accum(&num[0], &num[5]) << std::endl; char name[] = "templates"; // 创建字符值数组 int length = sizeof(name)-1; std::cout << "============= characters array =============" << std::endl; std::cout << "the total value of the characters in "" << name << "" is " << accum<char, 0, SumPolicy, AccumulationTraits<char>>(&name[0], &name[length]) << std::endl; std::cout << "the total value of the characters in "" << name << "" is " << accum<char, 0, SumPolicy>(&name[0], &name[length]) << std::endl; std::cout << "the total value of the characters in "" << name << "" is " << accum<char, 0>(&name[0], &name[length]) << std::endl; std::cout << "the total value of the characters in "" << name << "" is " << accum<char>(&name[0], &name[length]) << std::endl; std::cout << "the total value of the characters in "" << name << "" is " << accum<>(&name[0], &name[length]) << std::endl; std::cout << "the total value of the characters in "" << name << "" is " << accum(&name[0], &name[length]) << std::endl; system("pause"); return 0; }
输出结果:
============= integer array ============= <typename T, const int INITVAL, template <typename, typename> class Policy, typename Traits> ---> <T, INITVAL, Policy, Traits> the total value of the integer values is 120 <typename T, const int INITVAL, template <typename, typename> class Policy> ---> <T, INITVAL, Policy, AccumulationTraits<T>> the total value of the integer values is 120 <typename T, const int INITVAL> ---> <T, INITVAL, MultPolicy, AccumulationTraits<T>> the total value of the integer values is 120 <> ---> <int, 1, MultPolicy, AccumulationTraits<int>> the total value of the integer values is 120 <> ---> <int, 1, MultPolicy, AccumulationTraits<int>> the total value of the integer values is 120 <> ---> <int, 1, MultPolicy, AccumulationTraits<int>> the total value of the integer values is 120 ============= characters array ============= <typename T, const int INITVAL, template <typename, typename> class Policy, typename Traits> ---> <T, INITVAL, Policy, Traits> the total value of the characters in "templates" is 975 <typename T, const int INITVAL, template <typename, typename> class Policy> ---> <T, INITVAL, Policy, AccumulationTraits<T>> the total value of the characters in "templates" is 975 <typename T, const int INITVAL> ---> <T, INITVAL, MultPolicy, AccumulationTraits<T>> the total value of the characters in "templates" is 0 <typename T> ---> <T, 1, MultPolicy, AccumulationTraits<T>> the total value of the characters in "templates" is 465857536 <typename T> ---> <T, 1, MultPolicy, AccumulationTraits<T>> the total value of the characters in "templates" is 465857536 <typename T> ---> <T, 1, MultPolicy, AccumulationTraits<T>> the total value of the characters in "templates" is 465857536 请按任意键继续. . .