【问题标题】:Are ={} and {}-style initializations the same in C++11?={} 和 {} 风格的初始化在 C++11 中是否相同?
【发布时间】:2014-03-15 17:35:55
【问题描述】:

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

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

一样吗?

【问题讨论】:

  • 据我所知,是的

标签: c++ c++11 uniform-initialization list-initialization


【解决方案1】:

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

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&lt;int&gt;作为例子。

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

【讨论】:

  • 一个问题:我不明白为什么你可以简单地说std::array&lt;T,0&gt; a = {};(不是错误但可能会发出警告)而std::array&lt;T,0&gt; a{{}};是必要的。聚合类型还有其他区别吗?
  • @iavr 我不确定我是否遵循。 std::array&lt;T,0&gt; a = {};std::array&lt;T,0&gt; a{}; 都应该没问题。你用的是什么编译器?
  • 对不起,我的错误。示例应该是 std::array&lt;int,2&gt; a = {1, 2};std::array&lt;int,2&gt; b{{1, 2}};。在后者中需要双括号。
  • @iavr 这真的取决于你的编译器。在这两种情况下,我都收到了 clang 3.4 的警告,而 gcc 4.8.2 没有收到警告。我个人认为标准没有要求额外大括号的要求,但是对此很模棱两可。我认为这是针对 C++14 修复的。 (这可能是新版本的 gcc 不发出警告的原因:我很确定旧版本曾经这样做过。)
  • 谢谢,所以如果最终std::array&lt;int,2&gt; b{1, 2}; 有效并且适用于所有编译器,那么std::array&lt;T,0&gt; 就没有理由不为空,对吧?见Why is std::array< T, 0 > not empty?
【解决方案2】:

除了 juanchopanza 的 answer 中解释的区别之外,direct-list-initializationcopy-list-initialization 之间还有另一个区别,即重大更改当涉及到auto 并键入 braced-init-list 的推断。虽然是not added as part of 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

【讨论】:

  • 这不是为 C++14 投票的。请参阅论文末尾的最后一对问答。
  • @JamesMcNellis 谢谢,当它与 C++14 的其他论文一起出现时,我以为它已经出现了。确定答案。
【解决方案3】:

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

struct A { };

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-25
    • 2014-10-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多