[C ++ in-depth analysis] 44. In-depth analysis of class templates-template specialization

1 Multi-parameter class template

  • Class templates can define any number of different type parameters

Insert picture description here

Type 2 template specialization

Class templates can be specialized

  • Specify a specific implementation of the class template
  • Some type parameters must be specified explicitly
  • Implement class templates separately based on type parameters
  • The compiler automatically chooses the best

Insert picture description here

Class template specialization can be divided into partial specialization and complete specialization

  • Partial specialization-> constrain type parameters with specific rules
  • Full specialization-> fully display the specified type parameters

Insert picture description here
Programming experiment: class template specialization

// 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;
}
  • The above code first defines a template class, and then gives three specializations. Specialization is essentially the same class template. The compiler always chooses the best match for implementation.
  • t1.add (1, 2.5); call class test
  • t2.add (5, 5); call 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

Precautions:

  • Specialization essentially belongs to the same type of template, but is a separate implementation of the template
  • The use of special class templates is uniform, and each type parameter must be specified explicitly

3 Function template specialization

Function templates only support complete specialization of type parameters
Insert picture description here
Programming experiments: specialization of function templates

// 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) is a function template. The comparison of two floating-point numbers cannot directly use '==', so to achieve function template specialization bool Equal (double a, double b), the function template can only be completely specialized. The two are essentially the same template, but are implemented separately
  • bool Equal (double a, double b) is a function overload.
  • The compiler automatically chooses the best
  • Equal (1, 1) will select the template bool Equal (T a, T b)
  • Equal<>(0.01, 0.01) 使用模板 bool Equal<double>(double a, double b)
  • Equal (0.1, 0.1) uses the overloaded function bool Equal (double a, double b),

Compile and run

$ 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

Recommendation: When it is necessary to overload function templates, priority is given to using template specialization . When template specialization cannot meet the requirements, use function templates.

4 Summary

1. The class template can define any number of different type parameters
2. The class template can be partially specialized and completely specialized. Specialization is essentially a separate implementation of the template
3. The function template only supports full specialization

Published 298 original articles · praised 181 · 100,000+ views

Guess you like

Origin blog.csdn.net/happyjacob/article/details/104543091