2012-07-27 104 views
10

在下面的代碼段上不GCC-4.7.1編譯:函數默認模板參數可以放在非默認模板參數之前嗎?

struct X {}; 

template <class T = X, typename U> 
void f(const U& m) { 
} 


int main() { 
    f<>(0); 
} 

然而,這一個沒有:

struct X {}; 

template <class T = X, typename U> 
void f(const U& m) { 
    auto g = []() {}; 
} 


int main() { 
    f<>(0); 
} 

GCC-4.7.1抱怨:

c.cpp: In function 'void f(const U&)': 
c.cpp:5:15: error: no default argument for 'U' 

所以我的問題是:是否在函數模板中的非默認參數正確之前放置默認參數?如果是的話,爲什麼第二個不會編譯?如果否,爲什麼第一個編譯? C++ 11標準對此語法如何說明?

+0

http://stackoverflow.com/questions/2447458/default-template-arguments-for-function-templates – Andrew 2012-07-27 09:25:21

+0

@Andrew,你給的帖子太長了。你能指出哪個答案說的是否在非默認參數之前放置默認參數是正確的? – 2012-07-27 09:31:56

+1

@icando:標準中沒有*禁止*將函數模板的默認模板參數放在任何地方。只有* class *模板受到限制。 – 2012-07-27 09:43:30

回答

11

明確禁止使用類和別名。 n3290第14.1.11狀態:

如果一個類模板或別名模板的模板參數具有默認模板參數,以後每次 模板參數應要麼提供的默認模板參數,或者是模板參數 包

對於函數唯一的限制似乎與參數包:

函數模板的模板參數包不得緊接着又模板參數,除非該模板參數可以推斷或具有默認 參數

但顯然並不關心這種情況。

鑑於第14節中沒有任何內容禁止其用於功能,我們似乎必須假定它是允許的。

A note from a working group reports似乎證實這是意圖。該部分的原始建議措辭如下:

如果類模板的模板參數具有默認的模板參數,則所有後續的模板參數都應提供默認的模板參數。 [注:這不是函數模板的要求,因爲模板參數可能會被推斷(14.8.2 [temp.deduct])。]

我不能看到該說明在最終版本中去雖然。

+1

所以它是允許的,編譯器錯誤只是一個海灣合作委員會的錯誤? – 2012-07-27 09:46:50

+0

我*認爲*它是允許的。如果不是這個標準的缺陷,那就是沒有措辭拒絕它。在我的系統上鏗鏘聲也可以對它進行編譯,所以對於編譯器來說目前肯定是有問題的! – Flexo 2012-07-27 09:51:06

+1

我的MacPorts中的clang-3.2實際上編譯它。所以也許鏗鏘已經修復了? – 2012-07-27 09:55:38