C/C++ 萃取技术

【1】萃取技术基本概念演示

#include <iostream>
 
using namespace std;
 
namespace _nmsp1
{
    // 计算数组中元素的和值的函数模板
    template <typename T>
    T funcsum(const T* begin, const T* end)
    {
        T sum{}; // 零初始化,如果数值型变量被初始化为0,指针型变量被初始化为nullptr,bool类型变量被初始化为false
        for (;;)
        {
            sum += (*begin);
            if (begin == end)
                break;
            ++begin;
        }
        return sum;
    }
 
    // 新引入模板参数 U 表示结果类型
    template <typename U,typename T>
    U funcsum(const T* begin, const T* end)
    {
        U sum{};     // 零初始化,如果数值型变量被初始化为0,指针型变量被初始化为nullptr,bool类型变量被初始化为false
        for (;;)
        {
            sum += (*begin);
            if (begin == end)
                break;
            ++begin;
        }
        return sum;
    }
 
}
 
// 萃取技术及fixed traits(固定萃取)演示
// trait(萃取)技术用于对模板中的各种模板参数进行管理
// type traits:类型萃取
// 学习目的:
// (a)了解标准库中许多trait(萃取)技术的实现方法
// (b) 灵活运用并组合这些实现方法,写出功能强大,优雅和实用的代码
int main()
{
    // fixed traits(固定萃取):主要用于给定一种类型,萃取出另外一种类型;
 
    //(1)一个常规范例
    // SumFixedTraits固定萃取类模板的作用:通过类型,得到另外一个类型
 
    int myintarray1[] = { 10,15,20 };
    int myintarray2[] = { 1000000000,1500000000,2000000000 };     // 10亿,15亿,20亿
    char mychararray[] = "abc";                                    // 97,98,99
 
    cout << _nmsp1::funcsum(&myintarray1[0], &myintarray1[2]) << endl;          // int funcsum<int>(const int*,const int*);
    cout << _nmsp1::funcsum(&myintarray2[0], &myintarray2[2]) << endl;
    cout << (int)(_nmsp1::funcsum(&mychararray[0], &mychararray[2])) << endl;     // char funcsum<char>(const char*,const char*);
 
    int myintarray1[] = { 10,15,20 };
    int myintarray2[] = { 1000000000,1500000000,2000000000 };     // 10亿,15亿,20亿
    char mychararray[] = "abc";                                    // 97,98,99
    
    cout << _nmsp1::funcsum<__int64>(&myintarray1[0], &myintarray1[2]) << endl;        // __int64 funcsum<__int64,int>(const int*,const int*);
    cout << _nmsp1::funcsum<__int64>(&myintarray2[0], &myintarray2[2]) << endl;        // __int64 funcsum<__int64,int>(const int*,const int*);
    cout << (int)(_nmsp1::funcsum<int>(&mychararray[0], &mychararray[2])) << endl;    // int funcsum<int,char>(const char*,const char*);
 
    return 0;
}
#include <iostream>
 
using namespace std;
 
namespace _nmsp2
{
    // fixed traits类模板的泛化版本
    template<typename T>
    struct SumFixedTraits; // 不需要实现代码,因为不需要用该版本进行实例化
 
    // 各个fixed traits类模板的特化版本
    // (1) 给进来char类型时,返回的是int类型
    template <>
    struct SumFixedTraits<char>     // char表示给定的是char类型
    {
        using sumT = int;             // 类型别名sumT代表int类型(返回类型)
    };
 
    // (2) 给进来int类型时,返回的是__int64(long long/int64_t)类型
    template <>
    struct SumFixedTraits<int>         // int表示给进来的是int类型
    {
        using sumT = __int64;         // 类型别名sumT代表__int64类型(返回类型)
    };
    // (3)....其他给进来的是某个类型,返回的是另外一个类型,可以任意扩展出多个SumFixedTraits类模板的特化版本
 
    //-----------------------
    template <typename T>
    auto funcsum(const T* begin, const T* end)
    {
        using sumT = typename SumFixedTraits<T>::sumT;     // 给进来一个类型(T),返回一个类型(sumT),这是fixed traits的运用
        sumT  sum{};                                     // 零初始化,如果数值型变量被初始化为0,指针型变量被初始化为nullptr,bool类型变量被初始化为false
        for (;;)
        {
            sum += (*begin);
            if (begin == end)
                break;
            ++begin;
        }
        return sum;
    }
}
 
// 萃取技术及fixed traits(固定萃取)演示
// trait(萃取)技术用于对模板中的各种模板参数进行管理
// type traits:类型萃取
// 学习目的:
// (a)了解标准库中许多trait(萃取)技术的实现方法
// (b) 灵活运用并组合这些实现方法,写出功能强大,优雅和实用的代码
int main()
{
    // fixed traits(固定萃取):主要用于给定一种类型,萃取出另外一种类型;
    int myintarray1[] = { 10,15,20 };
    int myintarray2[] = { 1000000000,1500000000,2000000000 };     // 10亿,15亿,20亿
    char mychararray[] = "abc";                                    // 97,98,99
 
    cout << _nmsp2::funcsum(&myintarray1[0], &myintarray1[2]) << endl;  // sumT funcsum<int>(const int*,const int*);
    cout << _nmsp2::funcsum(&myintarray2[0], &myintarray2[2]) << endl;    // sumT funcsum<int>(const int*,const int*);
    cout << (int)(_nmsp2::funcsum(&mychararray[0], &mychararray[2])) << endl; // sumT funcsum<char>(const char*,const char*);
 
    return 0;
}

 

【2】由容器类型萃取元素类型

#include <iostream>
 
#include <vector>
#include <list>
 
using namespace std; 
 
namespace _nmsp1
{    
    // template <class T>
    // struct vector
    // {
    //     .....
    //     using value_type = T:
    // };
    
    // 常规实现版本
    /*
    // 泛化版本
    template <typename T>
    struct GetEleType;
 
    // 特化版本
    template <typename T>
    struct GetEleType<std::vector<T>>
    {
        using type = T;
    };
    
    template <typename T>
    struct GetEleType<std::list<T>>
    {
        using type = T;
    };
 
    template <typename T,std::size_t Size>     // 这个特化版本增加了一个模板参数
    struct GetEleType<T[Size]>                 // 萃取出数组元素个数
    {
        using type = T;
        static const std::size_t size = Size;
    };
    */
 
    // 泛化版本,用泛化版本实现对容器类型的支持
    template <typename T>
    struct GetEleType
    {
        using type = typename T::value_type;    // 针对容器
    };
 
    // 针对数组的特化版本(内容不变)
    template <typename T, std::size_t Size>        // 这个特化版本增加了一个模板参数
    struct GetEleType<T[Size]>                     // 萃取出数组元素个数
    {
        using type = T;
        static const std::size_t size = Size;
    };
 
    // 别名模板:
    template <typename T>
    using EleType = typename GetEleType<T>::type;
 
    //---------------------------------------------------------------------------
    // 函数模板
    template <typename T>
    void PrintEleType(const T& container)
    {
        cout << "容器(数组)的元素类型为:" << typeid(GetEleType<T>::type).name() << endl;
        cout << "容器(数组)的元素类型为:" << typeid(EleType<T>).name() << endl;
    }
}
 
// 萃取技术及fixed traits(固定萃取)演示
int main()
{
    //(3)通过容器(数组)类型萃取元素类型范例
    //(3.1)用GetEleType类模板进行常规实现
    //(3.2)引入函数模板PrintEleType
    //(3.2)GetEleType类模板的改进
 
    cout << "vector<double>的元素类型为:" << typeid(_nmsp1::GetEleType< vector<double> >::type).name() << endl;
    cout << "list<int>的元素类型为:" << typeid(_nmsp1::GetEleType< list<int> >::type).name() << endl;
    cout << "float[45]的元素类型为:" << typeid(_nmsp1::GetEleType< float[45] >::type).name() << endl;
    cout << "float[45]的数组元素数量为:" << _nmsp1::GetEleType< float[45] >::size << endl;
    
    vector<double> mydblvec;
    _nmsp1::PrintEleType(mydblvec);
 
    list<int> myintlist;
    _nmsp1::PrintEleType(myintlist);
 
    float myfloatarr[45];
    _nmsp1::PrintEleType(myfloatarr);
 
    cout << "vector<double>的元素类型为:" << typeid(vector<double>::value_type).name() << endl;
 
    return 0;
}

【3】引用类型的移除与添加

#include <iostream>
 
// 只在Debug(调试)模式下
#ifdef _DEBUG
#ifndef DEBUG_NEW
// 重新定义new运算符
#define DEBUG_NEW new(_NORMAL_BLOCK,__FILE__,__LINE__)
#define new DEBUG_NEW
#endif
#endif
 
#include <boost/type_index.hpp>
using namespace std;
 
namespace _nmsp1
{    
    template <class T1,class T2>
    void print_is_same()
    {
        cout << "T1类型为:" << typeid(T1).name() << endl;
        cout << "T2类型为:" << typeid(T2).name() << endl;
        cout << "T1类型和T2类型是否相等:" << std::is_same<T1, T2>() << endl;
        //
        // cout << "T1类型和T2类型是否相等:" << std::is_same<T1, T2>::value << endl;
        //         值为1则表示2个类型相等,值为0表示2个类型不等
        //         is_same是标准库中用于判断两个类型是否相同的类模板,
        //         std::is_same<T1,T2>()写法写成std::is_same<T1,T2>::value效果也是一样的
    }
 
    // c++14中定义了大量别名
    // template<class T>
    // using remove_reference_t = typename remove_reference<T>::type;
}
namespace _nmsp2
{
    // 泛化版本
    template <typename T>
    struct RemoveReference
    {
        using type = T;
    };
 
    // 特化版本
    template <typename T>
    struct RemoveReference<T&>
    {
        using type = T;
    };
    template <typename T>
    struct RemoveReference<T&&>
    {
        using type = T;
    };
    // 别名模板
    template <typename T>
    using RemoveReference_t = typename RemoveReference<T>::type;
}
 
namespace _nmsp3
{
    template<typename T>
    struct AddLValueReference
    {
        using type = T&;         // int && & ,引用折叠:有左值引用,结果必然为左值引用,所以type = int &
    };
    template<typename T>
    using AddLValueReference_t = typename AddLValueReference<T>::type;
    // 实际上可以直接简化为using AddLValueReference_t = T&;,这样就不用定义AddLValueReference了;
 
    //----------------------------------------------------------------------------------------------------------------------------------
    template<typename T>
    struct AddRValueReference
    {
        using type = T&&;
    };
    template<typename T>
    using AddRValueReference_t = typename AddRValueReference<T>::type;
    // 实际上可以直接简化为using AddRValueReference_t = T&&;,这样就不用定义AddRValueReference了
}
 
int main()
{     
    _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);    // 程序退出时检测内存泄漏并显示到“输出”窗口
 
    //(4)引用类型的移除和增加
    //(4.1)引用类型的移除
    // std::remove_reference类模板
    //(4.2)引用类型的增加:根据给定的类型来创建一个左值或者右值引用
    // std::add_lvalue_reference类模板:给定一个类型,返回该类型对应的左值引用类型
    // std::add_rvalue_reference类模板:给定一个类型,返回该类型对应的右值引用类型
    // std::is_lvalue_reference和std::is_rvalue_reference类模板:判断某个类型是否是左值引用类型或者右值引用类型
 
    std::remove_reference<int>::type a;
    std::remove_reference<int&>::type b;
    std::remove_reference<int&&>::type c;
 
    std::remove_reference_t<int> a;
    std::remove_reference_t<int &> b;
    std::remove_reference_t<int&&> c;
    _nmsp1::print_is_same<decltype(a), decltype(b)>();
    _nmsp1::print_is_same<decltype(a), decltype(c)>();
 
    int&& a2 = 12;
    // _nmsp2::RemoveReference_t<decltype(a2)> b2 = "dd";    // error C2440: “初始化”: 无法从“const char [3]”转换为“int”
    _nmsp2::RemoveReference_t<decltype(a2)> b2 = 125;
    int i = 64;
    int& c2 = i;
    _nmsp2::RemoveReference_t<decltype(c2)> d2 = 500;
    using boost::typeindex::type_id_with_cvr;
    cout << "b2= " << type_id_with_cvr<decltype(b2)>().pretty_name() << endl;
    cout << "d2= " << type_id_with_cvr<decltype(d2)>().pretty_name() << endl;
 
 
    int a = 15;
    std::add_lvalue_reference<decltype(a)>::type b = a;     // b的类型为int &
    std::add_rvalue_reference<decltype(a)>::type c = 16;    // c的类型为int &&
 
    using btype = std::add_lvalue_reference_t<int>;         // *_t是个别名模板
    cout << std::is_same<int&, btype>() << endl;              // 1
 
    using ctype = std::add_rvalue_reference_t<int>;
    cout << std::is_lvalue_reference<btype>::value << endl; // 1
    cout << std::is_rvalue_reference<ctype>::value << endl; // 1
 
    std::add_rvalue_reference_t<int&> cc1 = a;                 // cc1类型为int &,这里涉及到引用折叠, &和&& 折叠后得到 &
    std::add_rvalue_reference_t<int&&> cc2 = 16;             // cc2的类型为int &&,这里涉及到引用折叠,&&和&&折叠得到&&
 
 
    int anew = 15;
    _nmsp3::AddLValueReference_t<decltype(anew)> bnew = anew;         // decltype(anew)的类型是int,bnew的类型为int &
    int&& anew2 = 16;
    _nmsp3::AddLValueReference_t<decltype(anew2)> bnew2 = anew;        // decltype(anew2)的类型是int&&,bnew的类型为int &
 
    int argnew = 15;
    _nmsp3::AddRValueReference_t<decltype(argnew)> brgnew = 18;     // brgnew的类型为int &&
 
    int&& argnew2 = 15;
    _nmsp3::AddRValueReference_t<decltype(argnew2)> brgnew2 = 18;    // brgnew2的类型为int &&
 
    int tmpvalue = 16;
    int& argnew3 = tmpvalue;
    _nmsp3::AddRValueReference_t<decltype(argnew3)> brgnew3 = tmpvalue;    // brgnew3的类型为int &,因为根据引用折叠规则,左值引用和右值引用遇到一起,结果是左值引用
 
    return 0;
}

 

【4】退化技术

 

#include <iostream>
 
// 只在Debug(调试)模式下
#ifdef _DEBUG
#ifndef DEBUG_NEW
// 重新定义new运算符
#define DEBUG_NEW new(_NORMAL_BLOCK,__FILE__,__LINE__)
#define new DEBUG_NEW
#endif
#endif
 
#include <boost/type_index.hpp>
using namespace std;
 
template<typename T>
void myfunc(T tmprv)
{
    cout << "---------------------begin------------------------" << endl;
    using boost::typeindex::type_id_with_cvr;
    cout << "T=" << type_id_with_cvr<T>().pretty_name() << endl;                       // 显示T类型
    cout << "tmprv=" << type_id_with_cvr<decltype(tmprv)>().pretty_name() << endl;     // 显示tmprv类型
    cout << "----------------------end-------------------------" << endl;
}
 
namespace _nmsp1
{
    //------------------------------------------------------------------------------------------------
    // 去除引用修饰符
    //------------------------------------------------------------------------------------------------
    // 泛化版本
    template <typename T>
    struct RemoveReference
    {
        using type = T;
    };
 
    // 特化版本
    template <typename T>
    struct RemoveReference<T&>
    {
        using type = T;
    };
    template <typename T>
    struct RemoveReference<T&&>
    {
        using type = T;
    };
    // 别名模板
    template <typename T>
    using RemoveReference_t = typename RemoveReference<T>::type;
 
    //------------------------------------------------------------------------------------------------
    // 去除const修饰符
    //------------------------------------------------------------------------------------------------
    // 泛化版本
    template <typename T>
    struct RemoveConst
    {
        using type = T;
    };
    // 特化版本
    template <typename T>
    struct RemoveConst<const T>
    {
        using type = T;
    };
    // 根据需要增加其他特化版本....
 
    // 模板别名
    template <typename T>
    using RemoveConst_t = typename RemoveConst<T>::type;
 
    //------------------------------------------------------------------------------------------------
    // 去除const修饰符以及引用修饰符
    //------------------------------------------------------------------------------------------------
    template <typename T>
    struct RemoveCR :RemoveConst<typename RemoveReference<T>::type> // 把const和引用修饰符去掉
    {
 
    };
    // 模版别名
    template <typename T>
    using RemoveCR_t = typename RemoveCR<T>::type;
    /*template <typename T>
    using RemoveCR_t = RemoveConst_t<typename RemoveReference_t<T>>;*/
    //------------------------------------------------------------------------------------------------
    // 退化技术
    //------------------------------------------------------------------------------------------------
    // 泛化版本
    template<typename T>
    struct Decay :RemoveCR<T>
    {
    };
 
    // 特化版本,处理数组,该特化版本没有继承任何父类
    // 有边界数组转换成指针
    template<typename T,std::size_t size>
    struct Decay<T[size]>
    {
        using type = T*;
    };
 
    // 无边界数组转换成指针
    template<typename T>
    struct Decay<T[]>
    {
        using type = T*;
    };
 
    // 函数名变成函数指针等
    template <typename T,typename... Args>
    struct Decay<T(Args...)> // 返回类型是T,参数Args....
    {
        using type = T(*)(Args...);
    };
 
    // 模版别名
    template <typename T>
    using Decay_t = typename Decay<T>::type;
 
    // 测试函数
    //------------------------------------------------------------------------------------------------
    void testFunc() {}
 
    //------------------------------------------------------------------------------------------------
    void testFunc2()
    {
        cout << "testFunc2()执行了" << endl;
    }
}
 
void rfunc()
{
    cout << "rfunc执行了!" << endl;
}
 
extern int g_array[]; // 类型 int []
 
// 萃取技术及fixed traits(固定萃取)演示
int main()
{     
    _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);    // 程序退出时检测内存泄漏并显示到“输出”窗口
 
    //(5)const修饰符的移除RemoveConst类模板,与C++标准库里std::remove_const比较类似
    _nmsp1::RemoveConst_t<const int> nca = 15;    // nca是int类型
    nca = 18;                                     // 可以给nca重新赋值
 
    const int a = 16;
    const int& b = a;
    const int&& c = 18;
    int array[5] = { 1,2,3,4,5 };
    myfunc(a);
    myfunc(b);
    myfunc(c);
    myfunc(array);
    myfunc(_nmsp1::testFunc);
 
    //(6)退化(decay)技术
    // 退化:对于const int类型来说,int类型就是一种退化的表现
    // const修饰符和&、&&修饰符被丢弃,数组类型变成指针类型,函数名变成了函数指针等,都是类型上的退化表现
    // c++标准库:std::decay,该类模板的作用就是把类型退化掉(把类型中的修饰符丢弃掉)
    // 无边界数组,某个.cpp源文件中定义一个全局数组,如 int g_array[10]; int[10];
    // extern int g_array[]; // 外部变量说明
    // 基本概念:
    // a) 函数类型:由函数返回值和函数参数决定,testFunc2 代表的函数类型 void()
    // b) 可以利用函数指针指向某种函数类型,若要指向testFunc2,那么函数指针的类型就应该为void(*)()
    // c) 如果不为“函数名退化成函数指针”写一个Decay的特化版本,观察一些测试代码:给进去的是函数类型,返回的依旧是函数类型
    std::decay<const int&>::type nb = 26;
    cout << "nb的类型为:" << typeid(decltype(nb)).name() << endl;                 // nb类型为int类型
 
    _nmsp1::RemoveCR_t<const int&&> rcrobj = 16;                                 // rcrobj为int类型,移除了const与引用属性
 
    int arr[2] = { 1,2 };
    _nmsp1::Decay<decltype(arr)>::type myarray;                                    // 有边界数组转换成指针
    cout << "myarray类型为:" << typeid(decltype(myarray)).name() << endl;
 
    _nmsp1::Decay<decltype(g_array)>::type myarray2;                            // 无边界数组转换成指针
    cout << "myarray2类型为:" << typeid(decltype(myarray2)).name() << endl;
 
    void (*p) () = _nmsp1::testFunc2;                                             // 定义了一个函数指针,指向testFunc2函数
    p();                                                                         // 调用p指向的函数,调用的是testFunc2函数
 
    _nmsp1::Decay<decltype(_nmsp1::testFunc2)>::type rfunc;                     // 表面看起来此代码行定义了一个函数类型的变量rfunc,实际理解成函数声明更好
                                                                                // 类似于这种代码行的感觉:void rfunc();
 
    cout << "rfunc类型为:" << typeid(decltype(rfunc)).name() << endl;
    rfunc();                                                                    // 调用rfunc函数
 
    // 两种定义函数指针的方式
    // _nmsp1::Decay<decltype(_nmsp1::testFunc2)>::type rfunc;
    _nmsp1::Decay_t<decltype(_nmsp1::testFunc2)> rfunc;
    cout << "rfunc类型为:" << typeid(decltype(rfunc)).name() << endl;
    rfunc = _nmsp1::testFunc2;                                                     // 给函数指针赋值
    rfunc();                                                                     // 相当于调用了testFunc2函数
 
    return 0;
}

【5】策略技术

 

#include <iostream>
 
using namespace std;
 
namespace _nmsp1
{
    // 泛化版本
    // SumFixedTraits类模板
    template <typename T>
    struct SumFixedTraits;
 
    // 特化版本 char,转换为 int
    template<>
    struct SumFixedTraits<char>
    {
        using sumT = int;
        static sumT initValue() { return 0; }
    };
 
    // 特化版本 int,转换为 __int64
    template<>
    struct SumFixedTraits<int>
    {
        using sumT = __int64;
        static sumT initValue() { return 0; }
    };
 
    // 特化版本 double,转换为 double
    template<>
    struct SumFixedTraits<double>
    {
        using sumT = double;
        static sumT initValue() { return 0.0; }
    };
 
    //----------------------
    // 泛化版本
    template <typename T>
    struct MinFixedTraits;
    
    // 特化版本
    template<>
    struct MinFixedTraits<int>
    {
        using sumT = int;                             // 求最小值,结果类型与元素类型相同即可,为了名字统一,都用sumT这个名字
        static sumT initValue() { return INT_MAX; } // INT_MAX:整型最大值,任何一个数组元素都不会被这个值更大,因此可以顺利的找到数组元素中的最小值,参见MinPolicy::algorithm
    };
 
 
    //----------------------
    // 求和策略类以实现求和算法
    template <typename sumT, typename T>
    struct SumPolicy
    {
        // 静态成员函数模板
        static void algorithm(sumT& sum, const T& value)    // 策略类的核心算法
        {
            sum += value;                                    // 求和
        }
    };
 
    //----------------------
    //求最小值策略类
    template <typename minT, typename T>
    struct MinPolicy
    {
        static void algorithm(minT& min, const T& value)
        {
            if (min > value)
                min = value;
        }
    };
 
    //----------------------
    // funcsum函数模板
    // template <typename T, typename U = SumFixedTraits<T> >      // T = char , U = SumFixedTraits<char>
    template <typename T,
              typename U = SumFixedTraits<T>,
              // typename V = SumPolicy
              template<class,class> class V = SumPolicy            // 这里class也可以写成typename
    >
    auto funcsum(const T* begin, const T* end)
    {
        typename U::sumT sum = U::initValue();                  // typename SumFixedTraits<char>::sumT sum = SumFixedTraits<char>::initValue();
                                                                // int sum = 0;
        for (;;)
        {
            V<U::sumT,T>::algorithm(sum, *begin);                 // 捋一下:T是数组成员类型,U是固定萃取(fixed traits)类模板,
                                                                  // 从中可以提取出结算的结果类型(U::sumT)以及结果的初值,
                                                                  // V是策略类模板,用于实现具体算法(求和,求最小值等)
            if (begin == end)
                break;
            ++begin;
        }
        return sum;
    }
}
 
// 策略(policy)技术中的算法策略
int main()
{
    // 程序退出时检测内存泄漏并显示到“输出”窗口
    _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
    
    //(1)常规范例:普通策略类
    char mychararray[] = "abc";
    cout << (int)(_nmsp1::funcsum(&mychararray[0], &mychararray[2])) << endl;
 
    //(2)常规范例:策略类模板
    int myintarray1[] = { 10,15,20 };
    cout << (int)(_nmsp1::funcsum<int, _nmsp1::SumFixedTraits<int>, _nmsp1::MinPolicy>(&myintarray1[0], &myintarray1[2])) << endl;
    cout << (int)(_nmsp1::funcsum<int, _nmsp1::MinFixedTraits<int>, _nmsp1::MinPolicy>(&myintarray1[0], &myintarray1[2])) << endl;
 
    //(3)萃取(trait)技术与策略(policy)技术的比较
    // 两者之间的相同和不同之处:
    // a)两种技术都象一个中间件一样,夹在不同的功能代码之间,让代码之间的调用更加灵活
    // b)萃取技术:给定一个类型,萃取出另外一个类型或者另外一个值(注重于类型或者指定)
    //     策略技术:给定一个类型,萃取出一个算法或者是一个不同的功能实现(注重于动作或者行为)
    //      因此,在书写策略类(类模板)的时候通常都需要包含成员函数以实现指定的行为
    //      有时,萃取技术中也可能实现某些动作或者行为,所以从这个角度来讲,萃取技术与策略技术有时区分不是那么明显
    // c)萃取技术一般通过一个类模板来实现,通常包含类模板的泛化版本和多个特化版本;策略技术用普通类或者类模板都可以实现
 
    return 0;
}

 

https://coppersun.blog.csdn.net/article/details/115417893

posted @ 2024-05-11 11:30  白伟碧一些小心得  阅读(164)  评论(0编辑  收藏  举报