【C++深度解析】4四、類模板深度剖析--模板特化

1 多參數類模板

  • 類模板能夠定義任意多不一樣的類型參數

在這裏插入圖片描述

2 類模板特化

類模板能夠被特化ios

  • 指定類模板的特定實現
  • 部分類型參數必須顯示指定
  • 根據類型參數分開實現類模板
  • 編譯器自動擇優選擇

在這裏插入圖片描述

類模板特化能夠分爲部分特化和徹底特化兩種類型編程

  • 部分特化–>用特定規則約束類型參數
  • 徹底特化–>徹底顯示指定類型參數

在這裏插入圖片描述
編程實驗:類模板特化ide

// 44-1.cpp
#include<iostream>
using namespace std;
template<typename T1, typename T2>
class Test
{
public:
    void add(T1 a, T2 b)
    {
        cout << "void add(T1 a, T2 b)" << endl;
        cout << a + b << endl;
    }
};

template<typename T1, typename T2>
class Test<T1*, T2*>				// 關於指針的特化實現
{
public:
    void add(T1* a, T2* b)
    {
        cout << "void add(T1* a, T2* b)" << endl;
        cout << *a + *b << endl;
    }
};

template<typename T>
class Test<T, T>					// 當 Test 類模板的兩個類型參數徹底相同時,使用這個實現
{
public:
    void add(T a, T b)
    {
        cout << "void add(T a, T b)" << endl;
        cout << a + b << endl;
    }
    void print()
    {
        cout << "class Test<T, T>" << endl;
    }
};

template<>
class Test<void*, void*>			// 當 T1 == void* 而且 T2 == void* 時
{
public:
    void add(void* a, void* b)
    {
        cout << "void add(void* a, void* b)" << endl;
        cout << "Error to add void* param..." << endl;
    }
};
int main()
{
    Test<int, float>t1;			// 必須顯示指明每個類型參數
    Test<long, long>t2;
    Test<void*, void*>t3;

    t1.add(1, 2.5);
    t2.add(5, 5);
    t2.print();

    t3.add(NULL, NULL);

    Test<int*, double*>t4;
    int a = 1;
    double b = 0.1;
    t4.add(&a, &b);
    return 0;
}
  • 上面的代碼先定義了一個模板類,而後給出了三個特化實現。特化本質上是同一個類模板。編譯器老是選擇最匹配的進行實現。
  • t1.add(1, 2.5); 調用 class Test
  • t2.add(5, 5); 調用 class Test<T, T>
  • t3.add(NULL, NULL); 調用 class Test<void*, void*>
  • t4.add(&a, &b); 調用 class Test<T1*, T2*>
$ g++ 44-1.cpp -o 44-1
$ ./44-1
void add(T1 a, T2 b)
3.5
void add(T a, T b)
10
class Test<T, T>
void add(void* a, void* b)
Error to add void* param...
void add(T1* a, T2* b)
1.1

注意事項:函數

  • 特化本質上屬於同一類模板,只是模板的分開實現
  • 特化類模板的使用方式是統一的,必須顯示指定每個類型參數

3 函數模板特化

函數模板只支持類型參數徹底特化
在這裏插入圖片描述
編程實驗:函數模板特化spa

// 44-2.cpp
#include<iostream>
using namespace std;
template<typename T>
bool Equal(T a, T b)
{
    cout << "bool Equal(T a, T b)" << endl;
    return a == b;
}

template<>
bool Equal<double>(double a, double b)
{
    const double delta = 0.00000000000001;
    double r = a - b;
    cout << "bool Equal<double>(double a, double b)" << endl;
    return (-delta < r) && (r < delta);
}

bool Equal(double a, double b)
{
    const double delta = 0.00000000000001;
    double r = a - b;
    cout << "bool Equal(double a, double b)" << endl;
    return (-delta < r) && (r < delta);
}
int main()
{
    cout << Equal(1, 1) << endl;
    cout << Equal<>(0.01, 0.01) << endl;		// 指定使用模板
    cout << Equal(0.1, 0.1) << endl;
    return 0;
}
  • bool Equal(T a, T b) 是函數模板,兩個浮點數比較不能直接使用 ‘==’,因此實現函數模板特化 bool Equal(double a, double b),函數模板只能徹底特化。兩者本質上屬於同一模板,只是分開實現
  • bool Equal(double a, double b) 是函數重載。
  • 編譯器自動擇優選擇
  • Equal(1, 1) 將選擇模板 bool Equal(T a, T b)
  • Equal<>(0.01, 0.01) 使用模板 bool Equal<double>(double a, double b)
  • Equal(0.1, 0.1) 使用重載函數 bool Equal(double a, double b),

編譯運行指針

$ g++ 44-2.cpp -o 44-2
$ ./44-2
bool Equal(T a, T b)
1
bool Equal<double>(double a, double b)
1
bool Equal(double a, double b)
1

建議:就當須要重載函數模板時,優先考慮使用模板特化,當模板特化沒法知足要求時,再使用函數模板。code

4 小結

一、類模板能夠定義任意多個不一樣的類型參數
二、類模板能夠部分特化和徹底特化,特化本質上是模板的分開實現
三、函數模板只支持徹底特化blog

相關文章
相關標籤/搜索