此代碼在Visual Studio 2015更新3(此處爲visual C++ compiler online,並且在其他編譯器中我沒有在線嘗試過(GCC和CLANG),給出了一個重新聲明錯誤C++ 11在基於範圍的循環中重新聲明
vector<int> v = {1,2,3};
for (auto i : v) {
printf("%d ", i);
int i = 99;
printf("%d ", i);
}
輸出:1 99 2 99 3 99
VS C++編譯器的在線(版本:19.10.24903.0)警告有關此:
警告C4456:「我」隱藏以前的本地聲明
是否有在C++ 11規範一些空間,讓這兩種方案是有效的聲明?
在我看來,VS2015正在爲「自動i」創建一個範圍,併爲循環體創建一個範圍。
增加一個額外的範圍,因爲一個同事建議,編譯在我所測試過的其他的編譯器罰款(不,我想這一點,它只是出於好奇):
vector<int> v = {1,2,3};
for (auto i : v) {{
printf("%d ", i);
int i = 99;
printf("%d ", i);
}}
感謝
編輯: 好吧,看完這個問題Redeclaration of variable in range-based for loops和「Angew」的答案後,我相信VS其實是正確的。
我讀這裏:cpp reference
鑑於這種語法描述:
for (range_declaration : range_expression) loop_statement
,什麼這相當於:
{
auto && __range = range_expression ;
for (auto __begin = begin_expr, __end = end_expr;
__begin != __end; ++__begin) {
range_declaration = *__begin;
loop_statement
}
}
我明白loop_statement實際上是我的整個包括括號的塊,所以重定義確實在一個內部塊中,因此是有效的。
編輯2: 我最後的編輯,以供將來參考,讀傳統for循環語法是類似的情況(cpp for loop)作爲基於範圍的:
for (init-statement condition(optional); iteration_expression(optional)) statement
「上述語法產生的代碼等同於:」
{
init_statement
while (condition) {
statement
iteration_expression ;
}
}
所以回過頭來看,我也解釋/解析陳述作爲我的內在塊,包括大括號,對此,我至少會期望一個始終如一的行爲,在這個行爲中,我是編譯器。但是所有的編譯器都會爲傳統的for循環重新聲明錯誤。
我剛剛看到這個其他問題http://stackoverflow.com/questions/24526131/redeclaration-of-variable-in-range-based-for-loops,其中指出VS實際上是正確的 – francholi
for循環相當於while,你已經切斷了它後面的EXCEPT部分,它討論了標識符的作用域 – Cubbi