全特化/偏特化和类型萃取

全特化/偏特化

对模板的某些类型进行不同的处理

模板的全特化和偏特化

#include <iostream>
using namespace std;
template<typename T1, typename T2>
class Test
{
    public:
     Test()
     {
         cout << "模板类" <<endl; 
     }
    private:
    T1 t1;
    T2 t2;
};
template<typename T1>
class Test<T1, int>
{
    public:
     Test()
     {
         cout << "偏特化" << endl;
     }
};
template<>
class Test<int, int>
{
    public:
     Test()
     {
         cout << "全特化" << endl;
     }
};
int main()
{
    Test<double, double> test1; // 模板类
    Test<double, int> test2;// 偏特化
    Test<int, int> test3;// 全特化
    
    system("pause");
}

模板函数的全特化和偏特化

//模板函数  
template<typename T1, typename T2>  
void fun(T1 a , T2 b)  
{  
    cout<<"模板函数"<<endl;  
}  

//全特化  
template<>  
void fun<int ,char >(int a, char b)  
{  
    cout<<"全特化"<<endl;  
}  

//函数不存在偏特化:下面的代码是错误的  
/* 
template<typename T2> 
void fun<char,T2>(char a, T2 b) 
{ 
    cout<<"偏特化"<<endl; 
} 
*/ 

类型萃取

string在设计增容的时候,必须调用构造函数,不能简单的使用memcpy,(必须深拷贝),因此在memcpy的时候会造成野指针的访问。一个有效的解决方案时全部使用new,则对string这种类型作处理的时候,编译器会调用构造函数。

遗憾的是,在实际应用场景下,使用for 循环+new虽然可以避免崩溃,但却会大幅度牺牲效率(memcpy效率比其快得多)

一个改进版的解决方案是使用全特化

缺点是代码复用性差,难以考虑全面对所有类型做处理

类型萃取解决这种问题,兼顾代码复用性效率

类型萃取

定义__truetype和__falsetype

struct __truetype
{
};
struct __falsetype
{
};

定义需要特殊处理的类型

template<typename T>
struct TypeTraits
{
    typedef __truetype ISPODType;
};
template<>
struct TypeTraits<string>
{
    typedef __falsetype ISPODType;
};

类型萃取

template<typename T>
class Test
{
    public:
     Test(){}
     ~Test(){}
     void test()
     {
         test(typename TypeTraits <T>::ISPODType());
     } 
     void test(__truetype)
     {
         cout << "T is not string"<<endl;
     }
     void test(__falsetype)
     {
         cout << "T is string" << endl;
     }
};

完整代码

#include <iostream>
#include <string>
using namespace std;
struct __truetype
{
};
struct __falsetype
{
};
template<typename T>
struct TypeTraits
{
    typedef __truetype ISPODType;
};
template<>
struct TypeTraits<string>
{
    typedef __falsetype ISPODType;
};
template<typename T>
class Test
{
    public:
     Test(){}
     ~Test(){}
     void test()
     {
         test(typename TypeTraits <T>::ISPODType());//g++需要加typename vc则不需要
     } 
     void test(__truetype)
     {
         cout << "T is not string"<<endl;
     }
     void test(__falsetype)
     {
         cout << "T is string" << endl;
     }
};
int main()
{
    Test<int> test1;
    Test<string> test2;
    test1.test(); //T is not string 
    test2.test(); //T is string
    
    system("pause");
}

猜你喜欢

转载自www.cnblogs.com/7osen/p/11808644.html