- Expert C++
- Vardan Grigoryan Shunguang Wu
- 681字
- 2021-06-24 16:34:06
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:
- Perform overload resolution among regular functions and non-specialized templates.
- 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.
- Git Version Control Cookbook
- 編程的修煉
- Developing Middleware in Java EE 8
- 程序員考試案例梳理、真題透解與強(qiáng)化訓(xùn)練
- Mobile Device Exploitation Cookbook
- C編程技巧:117個問題解決方案示例
- jQuery技術(shù)內(nèi)幕:深入解析jQuery架構(gòu)設(shè)計與實(shí)現(xiàn)原理
- Go語言入門經(jīng)典
- Python 快速入門(第3版)
- Mastering Bootstrap 4
- iOS Development with Xamarin Cookbook
- Learning D3.js 5 Mapping(Second Edition)
- Responsive Web Design with jQuery
- 現(xiàn)代C++語言核心特性解析
- 生成藝術(shù):Processing視覺創(chuàng)意入門