• trait与policy模板应用简单示例


    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
    请按任意键继续. . . 
  • 相关阅读:
    idea 开发中常用的36个快捷键!
    算法学习一
    elastic-job-lite使用文档
    Windows使用Fiddler对手机抓包或调试本地计算机web站点方法
    Thread.join的作用和原理
    static修饰的代码块被称作静态代码块
    【Java面试题】52 java中会存在内存泄漏吗,请简单描述。
    数据类型 Object.keys,values,entries
    数据类型 Map and Set(映射和集合)
    数组映射到对象
  • 原文地址:https://www.cnblogs.com/lsgxeva/p/7785035.html
Copyright © 2020-2023  润新知