官术网_书友最值得收藏!

Specialization and overloading

Specialization allows us to customize the template code for a given set of template arguments. It allows us to define a special behavior for specific template arguments. A specialization is still a template; you still need an instantiation to get the real code (automatically by the compiler).

In the following sample code, the primary function template, T app_max(T a, T b), will return a or b based on the return of operator a>b, but we can specialize it for T = std::string so that we only compare the 0-th elements of a and b; that is, a[0] >b[0]:

//ch4_3_func_template_specialization.cpp
#include <iostream>
#include <string>

//Part A: define a primary template
template <class T> T app_max (T a, T b) { return (a>b?a:b); }

//Part B: explicit specialization for T=std::string,
template <>
std::string app_max<std::string> (std::string a, std::string b){
return (a[0]>b[0]?a:b);
}

//part C: test function
using namespace std;
void main(){
string a = "abc", b="efg";
cout << app_max(5, 6) << endl; //line A
cout << app_max(a, b) << endl; //line B

//question: what's the output if un-comment lines C and D?
//char *x = "abc", *y="efg"; //Line C
//cout << app_max(x, y) << endl; //line D
}

The preceding code defines a primary template first, and then it explicitly specializes T as std::string; that is, instead of comparing the values of a and b, we only care about a[0] and b[0] (the behavior of app_max() is specialized). In the test function, line A calls app_max<int>(int,int) and line B calls the specialized version because there is no ambiguity at the deduction time. If we uncomment lines C and D, the primary function template, char* app_max<char > (char*, char*), will be called, since char* and std::string are different data types.

Essentially, specialization somewhat conflicts with function overload resolution: the compiler needs an algorithm to resolve this conflict by finding the right match among the template and overloading functions. The algorithm for selecting the right function involves the following two steps:

  1. Perform overload resolution among regular functions and non-specialized templates.
  2. If a non-specialized template is selected, check if a specialization exists that would be a better match for it.

For example, in the following code block, we're declaring the primary (line 0) and specialized function templates (lines 1-4), as well as the overload functions (lines 5-6) of f()):

template<typename T1, typename T2> void f( T1, T2 );// line 0
template<typename T> void f( T ); // line 1
template<typename T> void f( T, T ); // line 2
template<typename T> void f( int, T* ); // line 3
template<> void f<int>( int ); // line 4
void f( int, double ); // line 5
void f( int ); // line 6

f() will be called several times in the following code block. Based on the preceding two-step rule, we can show which function is chosen in the comments. We'll explain the reason for doing this after:

int i=0; 
double d=0;
float x=0;
complex<double> c;
f(i); //line A: choose f() defined in line 6
f(i,d); //line B: choose f() defined in line 5
f<int>(i); //line C: choose f() defined in line 4
f(c); //line D: choose f() defined in line 1
f(i,i); //line E: choose f() defined in line 2
f(i,x); //line F: choose f() defined in line 0
f(i, &d); //line G: choose f() defined in line 3

For lines A and line B, since f() defined in lines 5 and line 6 are regular functions, they have the highest priority to be chosen, so f(i) and f(i,d) will choose them, respectively. For line C, because the specialized template exists, the f() generated from line 4 is a better match than what was created from line 1. For line D, since c is a complex<double> type, only the primary function template defined in line 1 matches it. Line E will choose f() that was created by line 2 because the two input variables are the same type. Finally, lines F and line G will pick up the functions created from the templates in lines 0 and 3, respectively.

Having learned about the functional templates, we will now move on to class templates.

主站蜘蛛池模板: 沛县| 宁阳县| 波密县| 容城县| 邵阳县| 永昌县| 海门市| 汝阳县| 平塘县| 肥乡县| 宜春市| 稷山县| 洪湖市| 万源市| 汾西县| 乌鲁木齐县| 广河县| 左云县| 武夷山市| 霍山县| 郸城县| 上饶市| 乐陵市| 将乐县| 秭归县| 偃师市| 南平市| 绥棱县| 介休市| 环江| 宁晋县| 青海省| 武安市| 青铜峡市| 静宁县| 中方县| 嵊泗县| 巨鹿县| 龙门县| 乌兰察布市| 旬阳县|