在c++ 11中,Are ={}和{}样式的初始化是相同的
Are ={} and {}-style initializations the same in C++11?
c++ 11引入了{}样式的初始化。但是这两种形式
T x {...};
T x = {...};
一样吗?
它们并不完全相同。也许这可以用一个反例来说明:
struct Foo
{
explicit Foo(std::initializer_list<int>) {}
};
int main()
{
Foo f0{1, 2, 3}; // OK
Foo f1 = {1, 2, 3}; // ERROR
}
因此,第二个变体要求该类型可以从初始化列表隐式构造,而第一个版本则不需要。注意,这同样适用于形式为Foo(int, int, int)
的构造函数。我随意选择了initializer_list<int>
作为例子。
这将影响遵循"显式无处不在"哲学编写的某些类型(即人们在c++ 03代码中将多参数构造函数标记为explicit
,即使在该标准中没有意义)
除了在juanchopanza的回答中解释的差异之外,当涉及到auto
和带括号的初始化列表的类型推导时,直接列表初始化和复制列表初始化之间还有另一个差异,一个突破性的变化。虽然它没有作为c++ 14的一部分添加(最后一个问题),但问题已经确定,何时实现取决于委员会。
auto foo = {42}; // deduces foo as an initializer_list<int>
auto foo{42}; // deduces foo as an int
因此,直接列表初始化永远不会从实参中推导出initializer_list
。因此,下面的代码将是病态的。
auto foo{1,2}; // cannot have multiple initializers for
// direct-list-initialization when deducing type
但这是可以的:
auto foo = {1,2}; // copy-list-initialization still deduces initializer_list<int>
同样适用于lambda表达式中的一般化捕获。引用N3912
[x{5}](){}; // x is int
[x{1,2}](){}; // ill-formed, no multiple initializers with direct-init
[x = {5}](){}; // ok, x is an initializer_list<int> with one element
[x = {1,2}](){}; // ok, x is an initializer_list<int> with two elements
语法在一种情况下使用它们意味着不同的东西
struct A { };
namespace X {
struct A final {};
struct A final = {};
}
在第一个例子中,我们定义了一个名为A
的结构体,在第二个例子中,我们定义了一个名为final
的对象。 相关文章:
- 是否可以初始化不可复制类型的成员变量(或基类)
- C++使用整数的压缩数组初始化对象
- C++初始化基类
- 多成员Constexpr结构初始化
- 复制列表初始化的隐式转换的等级是多少
- 内联映射初始化的动态atexit析构函数崩溃
- 如何在C++中初始化嵌套类中的2个memeber
- 如何声明特征矩阵,然后通过嵌套循环初始化它
- 没有用于初始化C++中的变量模板的匹配构造函数
- 在未初始化映射的情况下,将值插入到映射的映射中
- C++成员初始化
- 为什么在C++中首先初始化成员类
- 同时具有"聚合初始化"和"模板推导"
- 初始化具有非默认构造函数的std::数组项的更好方法
- 是否可以在编译时初始化数组,以便在运行时不会花费时间?
- 我可以使用条件运算符初始化C风格的字符串文字吗
- 在C和C++中初始化结构中的数组
- 标准是否使用多余的大括号(例如 T{{{10}}})定义列表初始化?
- 在函数内部的声明中初始化数组,并在外部使用它
- 继承:构造函数,初始化C++11中基类的类C数组成员