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

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.

主站蜘蛛池模板: 汾西县| 张家川| 虎林市| 西乌| 尤溪县| 新竹市| 遂川县| 南安市| 澄城县| 城口县| 红桥区| 绥江县| 宾川县| 建平县| 宣化县| 阿巴嘎旗| 博兴县| 扎鲁特旗| 海阳市| 五原县| 兴城市| 顺昌县| 文昌市| 睢宁县| 灵宝市| 永城市| 上栗县| 龙岩市| 常德市| 福安市| 南靖县| 晋州市| 宁化县| 金溪县| 全南县| 澜沧| 阜宁县| 彭水| 崇州市| 都江堰市| 淮阳县|