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

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.

主站蜘蛛池模板: 常州市| 隆德县| 吐鲁番市| 吕梁市| 凤翔县| 太康县| 阿拉善左旗| 家居| 贞丰县| 南通市| 都匀市| 黄陵县| 荔浦县| 灵石县| 罗甸县| 呼图壁县| 上思县| 周至县| 莱西市| 大竹县| 衡水市| 阳泉市| 扶沟县| 黑河市| 吉安县| 松原市| 涟水县| 陇南市| 黄陵县| 纳雍县| 滕州市| 博乐市| 莎车县| 顺义区| 丹凤县| 长顺县| 安义县| 抚顺市| 临夏市| 西平县| 湘西|