2016-11-09 56 views
9
enum class E { 
    One, 
    Two 
}; 

void foo(E value = decltype(value)::One) { 
} 

它可以用Clang(3.9)編譯,但不能用GCC 6.1編譯:value was not declared in this scope在其默認值內使用參數名稱 - 是否合法?

什麼編譯器是正確的?

+0

看起來像[這](http://stackoverflow.com/questions/1880866/c-c-default-argument-set-as-a-previous-argument)是答案,但我不是100%確定。留給別人去決定是否應該關閉它。 – NathanOliver

+0

@NathanOliver這個問題是關於訪問參數的值,這是不可能的一個很好的理由(評估順序),但我希望它的名稱和類型受制於不同的規則,因爲該原因不影響它們。 – Quentin

+0

@Quentin這就是爲什麼我沒有投票結束。標準的引用有*因此,函數的參數不應該用在默認參數表達式中,即使它們沒有被評估。*並且我不確定這是否適用於此。 – NathanOliver

回答

8

根據[basic.scope.pdecl]/1

申報的名點立即後其完整的 聲明符(第8條)和前的初始(如果有的話),除非 如下所述。

所以這個參數肯定是在那個時候聲明的。如何在decltype中使用它?措辭已經過時,無意中不允許。見core issue 2082

根據8.3.6 [dcl.fct.default]段落9,

每個函數被調用 爲相應的參數沒有參數時間默認參數進行評估。未指定函數參數的評估 的順序。因此,即使它們不是 求值,也不能使用默認參數中的參數 函數。這禁止使用的未計算的操作數參數, 例如,

void foo(int a = decltype(a){}); 

這一措辭早「未評估的操作數」(這句話的概念 「不評價」是指通話 的函數,其中實際參數被提供,因此 默認參數不被使用,而不是未評估的操作數),並且 不適用於這種情況。

所以quoted paragraph修正如下

甲參數不應顯示爲默認參數潛在評估表達。

由於decltype的操作數未被評估,所以現在沒問題,而GCC是錯誤的。

+1

這只是在草案中引入的,而不是在C++ 14中引入的。 http://wg21.cmeerw.net/cwg/issue2082 – vladon

+0

@vladon是的,我也發現,在krzaq的評論之後。 – Columbo

+0

GCC真的錯了還是隻需要更新它在C++ 17/1z上編譯的方式?看起來像在C++ 14中被禁止,所以你真的不能錯誤的GCC。 – NathanOliver