zoukankan      html  css  js  c++  java
  • 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
    请按任意键继续. . . 
  • 相关阅读:
    LeetCode Find Duplicate File in System
    LeetCode 681. Next Closest Time
    LeetCode 678. Valid Parenthesis String
    LeetCode 616. Add Bold Tag in String
    LeetCode 639. Decode Ways II
    LeetCode 536. Construct Binary Tree from String
    LeetCode 539. Minimum Time Difference
    LeetCode 635. Design Log Storage System
    LeetCode Split Concatenated Strings
    LeetCode 696. Count Binary Substrings
  • 原文地址:https://www.cnblogs.com/lsgxeva/p/7785035.html
Copyright © 2011-2022 走看看