模板与泛型 —— 模板的特化

2020-06-08  本文已影响0人  从不中二的忧伤
一、类模板特化
二、函数模板特化

特化: 模板是泛化的表现,可以指定不同类型做相同的表现。而特化是指对于某些特殊的类型(类型模板参数),进行特殊的处理。需要注意的是,必须先有了泛化版本,才会有对应的特化版本。


一、类模板特化
1、类模板全特化

a) 常规类模板全特化

#include <iostream>
using namespace std;

// 泛化版本 
template<typename T, typename U>
class Test{
public:
    Test()
    {
        cout << "Test<T, U>()" << endl; 
    }   
};

// 全特化版本,即所有类型模板参数都被指定 
template<>
class Test<int, int>{
public:
    Test()
    {
        cout << "Test<int, int>()" << endl;
    }
}; 

// 全特化版本可以有多个【类型模板参数】不同的版本 
template<>
class Test<double, double>{
public:
    Test()
    {
        cout << "Test<double, double>()" << endl;
    }
};

int main()
{
    // 编译器会优先选择满足条件的特化版本 
    Test<char, char> t1;
    Test<int, int> t2;
    Test<double, double> t3;
    return 0;   
} 

正确写法:

template<>
class Test<int, int>{
public:
    Test()
    {
        cout << "Test<int, int>::Test()" << endl;
    }
    // 特化版本成员函数需要在类内实现 
    void Func()
    {
        cout << "Test<int, int>::Func()" << endl;
    }
};

错误写法:

template<>
class Test<int, int>{
public:
    Test()
    {
        cout << "Test<int, int>::Test()" << endl;
    }
    void Func();
};

template<>
void Test<int, int>::Func()
{
    cout << "Test<int, int>::Func()" << endl;
}

报错信息:
[Error] template-id 'Func<>' for 'void Test<int, int>::Func()' does not match any template declaration



b) 特化成员函数

#include <iostream>
using namespace std;

// 泛化版本 
template<typename T, typename U>
class Test{
public:
    Test()
    {
        cout << "Test<T, U>()" << endl; 
    }
    
    void Func();
};

// 泛化版本成员函数
template<typename T, typename U>
void Test<T, U>::Func()
{
    cout << "Test<T, U>::Func()" << endl;   
} 

// 特化成员函数 
template<>
void Test<int, int>::Func()
{
    cout << "Test<int, int>::Func()" << endl;
}
 

int main()
{
    Test<char, char> t1;
    t1.Func();
    
    Test<int, int> t2;
    t2.Func();

    return 0;   
} 
2、类模板偏特化

a) 模板参数数量 —— 偏特化

// 模板参数数量 —— 偏特化 
template<typename U>
class Test<int, U, int>{
public:
    Test()
    {
        cout << "Test<int, U, int>::Test()" << endl;
    }
    
    void Func();
};

template<typename U>
void Test<int, U, int>::Func()
{
    cout << "Test<int, U, int>::Func()" << endl;
}

b) 模板参数范围 —— 偏特化

// 模板参数范围 —— 偏特化

template<typename T>
class Test{
public:
    Test()
    {
        cout << "Test<T>::Test()" << endl;
    }
    
    void Func();
}; 

template<typename T>
void Test<T>::Func()
{
    cout << "Test<T>::Func()" << endl;
}

// const 特化版本 
template<typename T>
class Test<const T>{
public:
    Test()
    {
        cout << "Test<const T>::Test()" << endl;
    }
    void Func();
};

template<typename T>
void Test<const T>::Func()
{
    cout << "Test<const T>::Func()" << endl;
}

// 指针* 特化版本 
template<typename T>
class Test<T*>{
public:
    Test()
    {
        cout << "Test<T*>::Test()" << endl;
    }
    void Func();
};

template<typename T>
void Test<T*>::Func()
{
    cout << "Test<T*>::Func()" << endl;
}

int main()
{
    Test<char> t1;
    t1.Func();
    
    Test<const char> t2;
    t2.Func();
    
    Test<char*> t3;
    t3.Func(); 

    Test<const char*> t4;   // <T*> 特化版本 
    t4.Func();
    
    Test<char* const> t5;   // <const T> 特化版本 
    t5.Func(); 

    return 0;   
} 

二、函数模板特化

a) 函数模板全特化

// 函数模板泛化版本
template<typename T, typename U>
void Func(T val1, U val2)
{
    cout << "Func<T, U>" << endl;
}

// 函数模板全特化版本
template<>
void Func<double, double>(double val1, double val2)
{
    cout << "Func<double, double>" << endl;
} 


int main()
{
    Func('a', 'b');
    Func(1.0, 2.0);
    
    return 0;
}



b) 函数模板偏特化

// 函数模板偏特化版本(不被允许) 
template<typename T>
void Func<T, double>(T val1, double val2)
{
    cout << "Func<T, double>" << endl;
} 

报错信息:
[Error] function template partial specialization 'Func<T, double>' is not allowed


模板定义、实现,建议都放在一个 .h 文件中。
同样,模板的泛化版本和特化版本建议放在一个 .h 文件中。
并且,应该让泛化版本放置于特化版本之前。

上一篇 下一篇

猜你喜欢

热点阅读