假設(shè)有一個(gè)接收universal references的模板函數(shù)foo,定義如下:
template<typename T>void foo(T&& t) { cout << "foo(T&& t)" << endl; }
如果想對某些類型做特殊處理,寫一個(gè)重載版本的foo,比如想對float類型做特殊處理,就寫一個(gè)接收float類型的foo:
void foo(float n) { cout << "foo(float n)" << endl; }
這樣,如果我們寫下 foo(1.0) 時(shí),理論上應(yīng)該輸出"foo(float n)",而實(shí)際上輸出結(jié)果為"foo(T&& t)"。為什么呢?因?yàn)椤癋unctions taking universal reference are the greediest functions in C++”,也就是說universal reference的函數(shù)能準(zhǔn)確匹配幾乎所有的類型。當(dāng)我們調(diào)用foo(1.0)時(shí),1.0被推導(dǎo)為double類型,如果調(diào)用foo(float n),就需要做narrow conversion,所以編譯器會(huì)認(rèn)為foo(T&& t)為更準(zhǔn)確的匹配,除非我們寫下foo(1.f)時(shí),才會(huì)調(diào)用foo(float)。只有在類型完全準(zhǔn)確匹配時(shí),才會(huì)調(diào)用重載版本,否則編譯器會(huì)始終認(rèn)為universal reference版本為準(zhǔn)確匹配。
這個(gè)問題在類繼承中會(huì)更為隱晦,假設(shè)有一個(gè)名為Base的class,Base有一個(gè)接收universal reference的模板構(gòu)造函數(shù),定義如下:
延伸閱讀
學(xué)習(xí)是年輕人改變自己的最好方式