#include<iostream>#include<vector>#include<string>#include<list>#include<iterator>#include<memory>#include<fstream>#include<algorithm>#include<functional>#include<map>#include<set>#include<sstream>usingnamespace std;template<typename T>intcompare(const T &v1,const T &v2){if(v1<v2)return-1;if(v2<v1)return1;return0;}intmain(){
cout <<compare(1,0)<< endl;// 1
vector<int> vec1{7,2,3}, vec2{4,5,6};
cout <<compare(vec1, vec2)<< endl;// 1}
580 非类型模板参数
#include<iostream>#include<vector>#include<string>#include<list>#include<iterator>#include<memory>#include<fstream>#include<algorithm>#include<functional>#include<map>#include<set>#include<sstream>usingnamespace std;template<unsigned N,unsigned M>intcompare(constchar(&p1)[N],constchar(&p2)[M]){returnstrcmp(p1, p2);}intmain(){// only compare the first letter
cout <<compare("hi","mom")<< endl;// -1}
#include<iostream>#include<vector>#include<string>#include<list>#include<iterator>#include<memory>#include<fstream>#include<algorithm>#include<functional>#include<map>#include<set>#include<sstream>usingnamespace std;template<typename T,typename F=less<T>>intcompare(const T &v1,const T &v2, F f=F()){if(f(v1, v2))return-1;if(f(v2, v1))return1;return0;}intmain(){bool i =compare(0,42);return0;}
595
#include<iostream>#include<vector>#include<string>#include<list>#include<iterator>#include<memory>#include<fstream>#include<algorithm>#include<functional>#include<map>#include<set>#include<sstream>usingnamespace std;template<classT=int>classNumbers{public:Numbers(T v=0):val(v){}private:
T val;};intmain(){
Numbers<longdouble> lots_of_precision;
Numbers<> average_precision;}
595 普通的类成员模板
#include<iostream>#include<vector>#include<string>#include<list>#include<iterator>#include<memory>#include<fstream>#include<algorithm>#include<functional>#include<map>#include<set>#include<sstream>usingnamespace std;classDebugDelete{public:DebugDelete(ostream &s=cerr):os(s){}template<typename T>voidoperator()(T *p)const{
os <<"deleting unique_ptr"<< endl;delete p;}private:
ostream &os;};// using as deletor of unique_ptr
unique_ptr<int, DebugDelete>p(newint,DebugDelete());intmain(){double*p =newdouble;
DebugDelete d;d(p);int*ip =newint(32);DebugDelete()(ip);}
596 类成员的模板
#include<iostream>#include<vector>#include<string>#include<list>#include<iterator>#include<memory>#include<fstream>#include<algorithm>#include<functional>#include<map>#include<set>#include<sstream>usingnamespace std;template<typename T>classBlob{template<typename It>Blob(It b, It e);private:
shared_ptr<vector<T>> data;};template<typename T>template<typename It>
Blob<T>::Blob(It b, It e):data(make_shared<vector<T>>(b, e)){}intmain(){}
597 实例化类成员模板
#include<iostream>#include<vector>#include<string>#include<list>#include<iterator>#include<memory>#include<fstream>#include<algorithm>#include<functional>#include<map>#include<set>#include<sstream>usingnamespace std;template<typename T>classBlob{public:template<typename It>Blob(It b, It e);private:
shared_ptr<vector<T>> data;};template<typename T>template<typename It>
Blob<T>::Blob(It b, It e):data(make_shared<vector<T>>(b, e)){}intmain(){int ia[]={0,1,2,3,4};
vector<long> vi ={0,1,2,3,4,5,6};
list<constchar*> w ={"now","is","the","time"};
Blob<int>a1(begin(ia),end(ia));
Blob<int>a2(vi.begin(), vi.end());
Blob<string>a3(w.begin(), w.end());}
601 类型转换与模板类型参数
#include<iostream>#include<vector>#include<string>#include<list>#include<iterator>#include<memory>#include<fstream>#include<algorithm>#include<functional>#include<map>#include<set>#include<sstream>usingnamespace std;template<typename T> T fobj(T t1, T t2){return t1;}template<typename T> T fref(const T& t1,const T& t2){return t1;}intmain(){
string s1("a value");const string s2("another value");fobj(s1, s2);fref(s1, s2);int a[10], b[42];fobj(a, b);// reference will not convert to pointer// fref(a, b);}
#include<iostream>#include<vector>#include<string>#include<list>#include<iterator>#include<memory>#include<fstream>#include<algorithm>#include<functional>#include<map>#include<set>#include<sstream>usingnamespace std;template<typename T>voidf1(T&){};template<typename T>voidf3(T&&){};intmain(){int i=1;f1(i);constint ci =2;f1(ci);// error// f1(2);f3(2);return0;}
609 接受右值引用模板函数的两种特例
#include<iostream>#include<vector>#include<string>#include<list>#include<iterator>#include<memory>#include<fstream>#include<algorithm>#include<functional>#include<map>#include<set>#include<sstream>usingnamespace std;template<typename T>
T fcn(T t){return t+1;}template<typename T>voidf3(T&& val){
T t = val;// copy
t =fcn(t);
cout <<"t: "<< t << endl;
cout <<"val: "<< val << endl;if(val == t){}}intmain(){f3(42);// t 43 val 42int a =42;f3(a);
cout <<"a: "<< a << endl;// t 43, val 43 a 43return0;}
614 引用的转发
#include<iostream>#include<vector>#include<string>#include<list>#include<iterator>#include<memory>#include<fstream>#include<algorithm>#include<functional>#include<map>#include<set>#include<sstream>usingnamespace std;template<typename F,typename T1,typename T2>voidflip1(F f, T1 t1, T2 t2){f(t2, t1);}voidf(int v1,int&v2){
cout << v1 <<" "<<++v2 << endl;}template<typename F,typename T1,typename T2>voidflip2(F f, T1 &&t1, T2 &&t2){f(t2, t1);}//void g(int &&i, int &j){// cout << i << " " << j << endl;//}intmain(){int a =42;f(42, a);
cout << a << endl;//43
a =42;flip1(f, a,42);
cout << a << endl;// 42
a =42;flip2(f, a,42);
cout << a << endl;// 43// error// a = 42;// flip2(g, a, 42); // 43// cout << a << endl; // 42return0;}
614 翻转函数的终极版本
#include<iostream>#include<vector>#include<string>#include<list>#include<iterator>#include<memory>#include<fstream>#include<algorithm>#include<functional>#include<map>#include<set>#include<sstream>usingnamespace std;voidg(int&&i,int&j){
cout << i <<" "<<++j << endl;}template<typename F,typename T1,typename T2>voidflip(F f, T1 &&t1, T2 &&t2){g(std::forward<T2>(t2), std::forward<T1>(t1));}intmain(){int a =42;flip(g, a,42);
cout << a << endl;// 43return0;}
616 模板的重载
#include<iostream>#include<vector>#include<string>#include<list>#include<iterator>#include<memory>#include<fstream>#include<algorithm>#include<functional>#include<map>#include<set>#include<sstream>usingnamespace std;template<typename T> string debug_rep(const T &t){
ostringstream ret;
ret << t;return ret.str();}template<typename T> string debug_rep(T *p){
ostringstream ret;
ret <<"pointer: "<< p;if(p){
ret <<" "<<debug_rep(*p);}else{
ret <<" null pointer";}return ret.str();}intmain(){
string s("hi");
cout <<debug_rep(s)<< endl;// hi
cout <<debug_rep(&s)<< endl;//pointer: 0034F7F4 hireturn0;}
615 优先选择普通函数而非模板
#include<iostream>#include<vector>#include<string>#include<list>#include<iterator>#include<memory>#include<fstream>#include<algorithm>#include<functional>#include<map>#include<set>#include<sstream>usingnamespace std;template<typename T> string debug_rep(const T &t){
ostringstream ret;
ret << t;return ret.str();}
string debug_rep(const string &s){return'"'+ s +'"';}intmain(){
string s("hi");
cout <<debug_rep(s)<< endl;// "hi"return0;}
619 可变参数模板
#include<iostream>#include<vector>#include<string>#include<list>#include<iterator>#include<memory>#include<fstream>#include<algorithm>#include<functional>#include<map>#include<set>#include<sstream>usingnamespace std;template<typename T,typename... Args>voidfoo(const T &t,const Args&... rest);intmain(){int i =0;double d =3.14;
string s ="how now brown cow";foo(i, s,42, d);foo(s,42,"hi");foo("hi");return0;}
#include<iostream>#include<vector>#include<string>#include<list>#include<iterator>#include<memory>#include<fstream>#include<algorithm>#include<functional>#include<map>#include<set>#include<sstream>usingnamespace std;template<typename T>intcompare(const T&,const T&){
cout <<"common type"<< endl;return1;}template<size_t N, size_t M>intcompare(constchar(&)[N],constchar(&)[M]){
cout <<"special type"<< endl;return0;}intmain(){constchar*p1 ="hi",*p2 ="mom";compare(p1, p2);// common typecompare("hi","mom");// common typereturn0;}
625 函数模板特例化
#include<iostream>#include<vector>#include<string>#include<list>#include<iterator>#include<memory>#include<fstream>#include<algorithm>#include<functional>#include<map>#include<set>#include<sstream>usingnamespace std;template<typename T>intcompare(const T&,const T&){
cout <<"common type"<< endl;return1;}// 函数模板特例化template<>intcompare(constchar*const&p1,constchar*const&p2){return2}intmain(){constchar*p1 ="hi",*p2 ="mom";compare(p1, p2);// common typecompare("hi","mom");// common typereturn0;}
628 类模板部分特例化
#include<iostream>#include<vector>#include<string>#include<list>#include<iterator>#include<memory>#include<fstream>#include<algorithm>#include<functional>#include<map>#include<set>#include<sstream>usingnamespace std;template<classT>struct book{typedef T type;public:voiddebug(){
cout <<"normal version"<< endl;}};template<classT>struct book<T&>{typedef T type;public:voiddebug(){
cout <<"left reference version"<< endl;}};template<classT>struct book<T&&>{typedef T type;public:voiddebug(){
cout <<"right reference version"<< endl;}};intmain(){int i=42;int& j = i;
book<decltype(42)> a;// normal version
a.debug();
book<decltype(j)> b;//left reference version
b.debug();
book<decltype(move(i))> c;// right reference version
c.debug();return0;}
629 特例化类成员
#include<iostream>#include<vector>#include<string>#include<list>#include<iterator>#include<memory>#include<fstream>#include<algorithm>#include<functional>#include<map>#include<set>#include<sstream>usingnamespace std;template<typename T>struct Foo{Foo(const T &t):mem(t){}voidBar(){
cout <<"normal bar"<< endl;}
T mem;};template<>void Foo<int>::Bar(){
cout <<"special bar"<< endl;}intmain(){
Foo<int>f1(2);
f1.Bar();// special bar
Foo<string>f2("ah");
f2.Bar();// normal barreturn0;}