【问题标题】:What's the difference between parentheses and braces in c++ when constructing objectsc++构造对象时括号和大括号有什么区别
【发布时间】:2019-08-01 08:30:40
【问题描述】:

(){}在构造对象时有什么区别?

我认为 {} 应该只支持 initializer_list 或数组,但是当我在 snip 下运行时,我感到困惑。

#include <iostream>
using namespace std;
struct S {
    int v=0;
    S(int l) : v(l) {
    }
};


int main()
{
    S s1(12); // statement1
    S s2{12}; // statement2
    cout << s1.v << endl;
    cout << s2.v << endl;
}

statement1 是对的,因为() 是构造对象的基本语法。

我预计statement2 会编译失败。我认为{} 只能用于数组或initializer_list 类型。但实际结果编译完美,没有错误。

我错过了什么?

【问题讨论】:

  • 你错过了统一初始化,如果你没听说过你应该搜索它,它是c++11中的一件大事
  • 我个人建议避免使用它:std::vector&lt;int&gt; v{10, 12} - 你认为它会产生什么?有了std::vector&lt;int&gt; v(10, 12)std::vector&lt;int&gt; v({10, 12}),一切都变得更加清晰......

标签: c++ c++11 initialization


【解决方案1】:

对于S,它们具有相同的效果。两者都调用构造函数S::S(int) 来初始化对象。

S s2{12}; 被视为list initialization (C++11 起); S不是聚合类型也不是std::initializer_list,也没有构造函数取std::initializer_list,那么

如果前一阶段没有产生匹配,T 的所有构造函数都参与重载决议,反对由括号初始化列表的元素组成的参数集,限制只有非缩小转换被允许。

你也这么认为

我认为{} 只能用于数组或initializer_list 类型。

这不是真的。列表初始化的效果是,例如如果S是聚合类型,则执行聚合初始化;如果Sstd::initializer_list 的特化,则将其初始化为std::initializer_list;如果S 有一个采用std::initializer_list 的构造函数,那么它将首选用于初始化。您可以参考the page链接了解更多详细信息。

PS:S s1(12); 执行direct initialization

【讨论】:

    猜你喜欢
    • 2014-09-30
    • 2013-04-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-11
    • 2021-05-16
    • 1970-01-01
    • 2021-05-23
    • 2021-05-12
    相关资源
    最近更新 更多