为什么我可以从{}初始化一个常规数组,但不能从std::数组初始化?
Why can I initialize a regular array from {}, but not a std::array
这行得通:
int arr[10] = {};
arr
的所有元素值初始化为0。
为什么不工作:
std::array<int, 10> arr({});
我从g++(版本4.8.2)得到以下警告:
警告:成员' std::array<int,>::_M_elems '缺少初始化式
有两个问题一个是风格问题,另一个是警告问题。
虽然可能不明显,聚合初始化发生在临时对象上,然后将其用作复制构造函数的参数。更习惯的初始化方式如下:
std::array<int, 10> arr = {};
尽管这仍然留下警告。
警告包含在gcc bug report: - - wmissing -field-initializers放松请求中,其中一条注释说:
[…当然,MyType x = {};应该得到支持,如下所示:
http://en.cppreference.com/w/cpp/language/aggregate_initialization,例如:
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一起工作。
我们可以在Clang开发者列表的头部看到这个主题:- wmissing -field-initializer
参考c++ 11标准草案8.5.1
[dcl.init]章节。aggr] 说:
如果列表中的初始化子句比实际的少成员,则每个成员未显式初始化应该从一个空的初始化列表初始化(8.5.4)。(例子:
struct S { int a; const char* b; int c; }; S ss = { 1, "asdf" };
将ss.a初始化为1,将ss.b初始化为"asdf",将ss.c初始化为值为形式为int()的表达式,即0。-end example]
所以这是有效的c++,虽然注意到使用{}
是无效的C99。有人可能会说这只是一个警告,但这似乎是使用{}
进行聚合初始化的惯用c++,如果我们使用-Werror
将警告转换为错误,则会出现问题。
首先,您可以将({})
初始化器与std::array
对象一起使用,但在语义上,它代表使用临时值初始化的std::array
对象的复制构造函数进行直接初始化,即相当于
std::array<int, 10> arr(std::array<int, 10>{});
它实际上应该编译。
其次,当你可以直接执行
时,你真的不必走({})
的路std::array<int, 10> arr = {};
或
std::array<int, 10> arr{};
两者中的第一个在语法上与您的int arr[10] = {};
最相似,这让我想知道为什么您一开始没有尝试它。当您构建= {}
语法的std::array
版本时,为什么决定使用({})
而不是= {}
?
在编译-Werror
时,有足够多的人指出这是一个"问题",我认为值得一提的是,如果你只是加倍,问题就会消失:
std::array<int, 10> arr{{}};
在gcc 4.9.2上不为我产生任何警告。
我的理解是std::array实际上是一个类,它的唯一成员是C数组。所以双花括号是有意义的:外面的花括号表示你正在初始化类,然后里面的花括号默认初始化类中唯一的成员。由于类中只有一个变量时不存在可能的歧义,因此仅使用一对{}应该是合理的,但gcc在这里过于迂腐,并警告。
- C++使用整数的压缩数组初始化对象
- C++17中函数模板中的静态数组初始化(MSVC 2019)
- 从另一个静态常量数组初始化静态常量数组(只需少量计算)
- 在 Python 和 c++ 2d 数组初始化之间.这是怎麽?为什么呢?
- 字节数组初始化会导致 DirectX 崩溃
- 使用 new 和 值进行数组初始化,但没有显式数量的元素
- 运行时C++数组初始化问题
- 使用带有参数包的数组的成员数组初始化类
- 仅通过C++中数组初始化的不同方法,即可在同一输入上获得两个不同的答案
- C++ 2 个指针数组初始化 C2440
- C++结构字符数组初始化
- C++中的多维数组初始化
- constexpr数组初始化
- C++引物动态数组初始化程序的数目超过大小
- 使用std::index_sequence对std::数组初始化进行包扩展
- 当 std 数组初始化太小时,C++会引发错误吗?
- 如何确定结构数组初始化的大小?
- Qt并发错误:数组初始化需要大括号括起来的初始值设定项列表
- 此代码中的数组初始化样式是什么?这是标准的吗?
- C++ 使用数组初始化时的 STL 向量内存管理