Alw*_*ing 10 c++ compiler-warnings aggregate-initialization c++11 g++4.8
这有效:
int arr[10] = {};
Run Code Online (Sandbox Code Playgroud)
所有元素arr都被初始化为零.
为什么这不起作用:
std::array<int, 10> arr({});
Run Code Online (Sandbox Code Playgroud)
我从g ++(版本4.8.2)收到以下警告:
警告:缺少成员'std :: array <int,10ul> :: _ M_elems'的初始值设定项
Sha*_*our 12
有两个问题,一个是风格和警告问题.
尽管可能并不明显,但聚合初始化正在临时进行,然后将其用作复制构造函数的参数.这种初始化的惯用程度越大,如下:
std::array<int, 10> arr = {};
Run Code Online (Sandbox Code Playgroud)
虽然这仍然留下了警告.
该警告由gcc bug报告涵盖: - -Wmissing-field-initializers放宽请求,其中一条评论说:
[...]当然,说MyType x = {}的C++语法; 应该得到支持,如下所示:
http://en.cppreference.com/w/cpp/language/aggregate_initialization
例如:
Run Code Online (Sandbox Code Playgroud)struct S { int a; float b; std::string str; }; S s = {}; // identical to S s = {0, 0.0, std::string};这不应该因为早先评论中提到的原因而发出警告.
后续评论说:
我关于零初始化的陈述是不准确的(谢谢),但一般的观点仍然存在:在C中你必须写'= {0}',因为该语言不支持空括号初始化器(你得到一个警告 - -pedantic ); 在C++中,您可以编写'= {}'或'T foo = T();',但您不需要专门编写'= {0}'.
最新版本的gcc在这种情况下不会产生此警告,请参阅它与gcc 5.1一起使用.
我们可以在thead中的Clang Developers列表中看到这个主题:-Wmissing-field-initializers.
作为参考,草案C++ 11标准部分8.5.1 [dcl.init.aggr]说:
如果列表中的initializer-clause少于聚合中的成员,则未显式初始化的每个成员都应从空的初始化列表(8.5.4)初始化.[例如:
Run Code Online (Sandbox Code Playgroud)struct S { int a; const char* b; int c; }; S ss = { 1, "asdf" };使用"asdf"初始化ss.a,使用"asdf"初始化ss.b,使用int()形式的表达式的值初始化ss.c,即0.-末端示例
因此这是有效的C++,尽管如上所述使用的{}是无效的C99.有人可能会说它只是一个警告,但这似乎是惯用的C++ {}用于聚合初始化,如果我们-Werror用于将警告变成错误,则会出现问题.
首先,您可以将({})初始化程序与std::array对象一起使用,但在语义上代表使用临时值初始化std::array对象的复制构造函数进行直接初始化,即它等效于
std::array<int, 10> arr(std::array<int, 10>{});
Run Code Online (Sandbox Code Playgroud)
它实际上应该编译.
其次,({})当你可以做的时候,你真的不需要走的路
std::array<int, 10> arr = {};
Run Code Online (Sandbox Code Playgroud)
要么
std::array<int, 10> arr{};
Run Code Online (Sandbox Code Playgroud)
这两个中的第一个在语法上与你的最相似int arr[10] = {};,这让我想知道为什么你最初没有尝试它.您为什么决定使用({})而不是= {}在构建语法std::array版本时使用= {}?