最新的 Visual Studio 2019 使用/Wall命令列開關編譯以下代碼(啟用所有警告):
struct A{};
void f( const std::array<A, 2> & ) {}
int main() {
A x, y;
f( { x, y } );
}
列印警告:
warning C5246: 'std::array<A,2>::_Elems': the initialization of a subobject should be wrapped in braces
然而 GCC 和 Clang 都接受了最迂腐的錯誤檢查代碼,演示:https : //gcc.godbolt.org/z/Ps6K6jK1G
實際上,所有編譯器都接受呼叫 f( { { x, y } } );
MSVC 是否正確地建議它支持更簡單的形式而不需要額外的括號?
uj5u.com熱心網友回復:
Visual Studio 2019 具有CWG 缺陷 #1270并提供舊的初始化行為。
std::array 被定義為包含另一個聚合的聚合。
C 17 標準(11.6.1 聚合)
可以在初始化串列中省略 12 個大括號,如下所示。如果初始值設定項串列以左大括號開頭,則后續的初始值設定項子句的逗號分隔串列將初始化子聚合的元素;初始化器子句比元素多是錯誤的。然而,如果子集合的初始化器串列不以左大括號開頭,則僅從串列中獲取足夠的初始化器子句來初始化子集合的元素;留下任何剩余的初始化子句來初始化聚合的下一個元素,當前子聚合是該聚合的一個元素。
你可以想象std::array<A, 2>成
struct Array {
A sub[2];
};
根據參考Array a {{x, y}}是正確的,但已過時,內大括號是封閉陣列的聚合初始化。
有用的執行緒為什么 std::vector 和 std::array 的 C initializer_list 行為不同?.
uj5u.com熱心網友回復:
我相信 Clang 和 GCC 現在默認抑制該錯誤,以便警告不會透露實作的細節。話雖如此,VS 過去在使用 C 11 時不會給我一個錯誤,而 Clang 卻給了我一個錯誤(所以他們似乎已經在這個問題上發生了翻天覆地的變化)。所有檔案都表明雙花括號是最合適的,添加它們以匹配行業標準代碼實踐可能是有意義的。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/368213.html
