根据GCC 4.6.3(Ubuntu/Linaro 4.6.3-1ubuntu5),我在以下代码中的数组初始化中缺少大括号:
#include <iostream>
#include <boost/array.hpp>
#include <array>
int main(){
int plain[] = {1,2,3,4,5};
std::array <int, 5> std_arr = {1,2,3,4,5}; // warning, see below
boost::array<int, 5> boost_arr = {1,2,3,4,5}; // warning, see below
std::cout << plain[0] << std_arr[1] << boost_arr[2] << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
> g++ test.cc -Wall -Wextra -pedantic --std=c++0x
test.cc: in function »int main()«:
test.cc:7:47: warning: curly braces missing around initialization for »std::array::value_type [5] {aka int [5]}« [-Wmissing-braces]
test.cc:8:47: warning: curly braces missing around initialization for »int [5]« [-Wmissing-braces]
显然(GCC缺少初始化程序的大括号)这是GCC中的一个错误,即使在稍微不同的上下文中也是如此.答案不同于"提交错误报告"到"只是禁用警告".
但是,在std::array或者boost::array,这个警告是多余的,还是我错过了重要的事情?
(我可能会添加额外的括号,而不是禁用警告,但我很好奇其含义)
小智 4
我想这已经在这里得到了回答.
std :: array很有趣.它的定义基本上是这样的:
template struct std :: array {T a [size]; };
它是一个包含数组的结构.它没有采用初始化列表的构造函数.但是std :: array是C++ 11规则的聚合,因此它可以通过聚合初始化来创建.要聚合初始化结构内的数组,您需要第二组花括号:
std :: array strings = {{"a","b"}};
请注意,该标准确实表明在这种情况下可以省略额外的括号.所以它可能是一个GCC错误.
我认为这可能与这个缺陷有关,这个缺陷已经在几个问题中联系起来.
这是一个答案:
但是,这些额外的括号只能在"形式为T x = {a}"的声明中被省略; (C++11§8.5.1/ 11),即使用旧样式=时.允许括号省略的此规则不适用于直接列表初始化.这里的脚注如下:"在列表初始化的其他用途中不能省略大括号."
有关此限制的缺陷报告:CWG缺陷#1270.如果采用提议的解决方案,将允许使用大括号来进行其他形式的列表初始化,...
我注意到错误没有出现在gcc 4.8.1中,但它确实在一个非常旧的版本(4.4.7)上,我认为这是补丁(因为缺陷建议的解决方案是在2012年2月,这个链接是2012年3月):
http://gcc.gnu.org/ml/gcc-patches/2012-03/msg00215.html