12

C++11 引入了 {} 样式的初始化。但是这两种形式

T x {...};
T x = {...};

相同?

4

3 回答 3

13

它们并不完全相同。也许这可以通过一个反例来说明:

struct Foo
{
  explicit Foo(std::initializer_list<int>) {}
};

int main()
{
  Foo f0{1, 2, 3};    // OK
  Foo f1 = {1, 2, 3}; // ERROR
}

因此,第二个变体要求类型可以从初始化列表中隐式构造,而第一个版本则不需要。请注意,这同样适用于 form 的构造函数Foo(int, int, int)。我initializer_list<int>随意选择了作为例子。

这将影响某些遵循“显式无处不在”哲学编写的类型(人们explicit在 C++03 代码中标记了多参数构造函数,即使它在该标准中没有意义。)

于 2014-03-15T17:39:13.733 回答
5

除了 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
于 2014-03-15T17:58:15.263 回答
1

在一种情况下使用它们的语法意味着不同的东西

struct A { };

namespace X {
  struct A final {};
  struct A final = {};
}

在第一种情况下,我们定义了一个名为 的结构A,在第二种情况下,我们定义了一个名为 的对象final

于 2014-03-15T19:39:58.403 回答