2016-08-25 65 views
8

默認模板參數是否可以使用「默認值」的方式,不是從右側開始?默認模板參數 - 不一定是從正確的?它爲什麼有效?

準則是什麼?
編譯器將如何解釋?

例如,我很驚訝,此代碼工作

#include <iostream> 
using namespace std; 

template <bool T=true, class U> //"default" from LEFT-most parameter 
void f(U u){ 
    if(T){ cout<<true;} 
    else cout<<false; 
} 
int main() { 
    auto x = [](){ }; 
    f(x); 
    return 0; 
} 

見現場演示這裏:https://ideone.com/l6d9du

回答

8

模板參數推導在這裏很有效,因爲對於函數模板,隨後的模板參數可以由函數參數推導出來。在這種情況下,可以從函數參數u推導出模板參數U。請注意,對於類模板,如您預期的那樣,默認模板參數之後的後續模板參數應具有默認模板參數或模板參數包。

$14.1/11 Template parameters [temp.param]

如果一個類模板,可變模板,或 別名模板的模板參數具有默認模板參數的,每個隨後的 模板參數應由具有缺省模板的參數 提供或作爲模板參數包。如果 主要類模板,主要變量模板或別名模板 的模板參數是模板參數包,則它應該是最後一個模板參數。 函數模板的模板參數包不能被其他模板參數跟在 之後,除非該模板參數可以是從函數 模板的參數類型列表([dcl.fct])推導的 ,或者具有默認參數([temp.deduct])。 沒有默認參數的扣減指南模板([temp.deduct.guide])的模板 參數應從扣除指南模板的 參數類型列表中扣除。 [示例:

template<class T1 = int, class T2> class B; // error 

// U can be neither deduced from the parameter-type-list nor specified 
template<class... T, class... U> void f() { } // error 
template<class... T, class U> void g() { } // error 

- 結束舉例]

你可以試着讓U undeducible,看看會發生什麼:

template <bool T=true, class U> //"default" from LEFT-most parameter 
void f(){ 
    if(T){ cout<<true;} 
    else cout<<false; 
} 
int main() { 
    f();   // Fail. Can't deduce U. 
    f<true>();  // Fail. Can't deduce U. 
    f<true, int>(); // Fine. T=true, U=int. 
    return 0; 
} 

注意你必須明確地指定所有的模板參數使代碼工作,這使得默認的模板參數完全沒有意義。如果要使f()f<true>()正常工作,則還需要將U也設爲默認模板參數(或使其成爲模板參數包)。

template <bool T=true, class U=int> 
void f(){ 
    if(T){ cout<<true;} 
    else cout<<false; 
} 
int main() { 
    f();    // Fine. T=true, U=int 
    f<false>();  // Fine. T=false, U=int 
    f<false, char>(); // Fine. T=false, U=char 
    return 0; 
} 
4

你可以提供一個默認的任何參數。

如果你想使用默認,你不能明確指定參數在默認參數的右邊。但是,在您的示例中,U正在從函數的參數類型中推導出來,並且T正在默認。

相關問題