【问题标题】:Calling constructor with braces用大括号调用构造函数
【发布时间】:2013-03-02 00:37:20
【问题描述】:

关于 C++11 语法的简单问题。有一个示例代码(从source减少一个)

struct Wanderer
{
  explicit Wanderer(std::vector<std::function<void (float)>> & update_loop)
  {
    update_loop.emplace_back([this](float dt) { update(dt); });
  }
  void update(float dt);
};

int main()
{
  std::vector<std::function<void (float)>> update_loop;
  Wanderer wanderer{update_loop}; // why {} ???
}

我想知道,如何使用大括号调用构造函数,例如Wanderer wanderer{update_loop}; 它既不是初始化列表,也不是统一初始化。这是什么东西?

【问题讨论】:

  • 但是是统一初始化。大括号可用于调用构造函数,但始终首选采用 std::initializer_list 类型的构造函数。
  • // why {} ??? -- 好问题。没有理由比Wanderer wanderer(update_loop) 更喜欢这个。
  • @ipc 在某些情况下,它可以避免最麻烦的解析。
  • @juanchopanza:但在其他情况下,它可以一次默默地改变代码的含义。我不喜欢“统一”初始化。
  • @ipc 当然,这是这个初始化的一个非常丑陋的特性。

标签: c++ c++11 constructor


【解决方案1】:

既不是初始化列表,也不是统一初始化。这是什么东西?

你的前提是错误的。它是统一初始化,用标准术语来说,是direct-brace-initialization

除非存在接受std::initializer_list 的构造函数,否则使用大括号构造对象等同于使用圆括号。

使用大括号的好处是语法不受Most Vexing Parse问题的影响:

struct Y { };

struct X
{
    X(Y) { }
};

// ...

X x1(Y()); // MVP: Declares a function called x1 which returns
           // a value of type X and accepts a function that
           // takes no argument and returns a value of type Y.

X x2{Y()}; // OK, constructs an object of type X called x2 and
           // provides a default-constructed temporary object 
           // of type Y in input to X's constructor.

【讨论】:

  • "除非存在接受 std::initializer_list 的构造函数,否则..." 如果存在这样的构造函数?
【解决方案2】:

这只是 C++11 语法。您可以使用花括号初始化对象并调用其构造函数。您只需要记住,如果该类型具有 initializer_list 构造函数,则该构造函数具有优先权。

【讨论】:

    猜你喜欢
    • 2015-06-29
    • 2015-09-25
    • 2020-05-28
    • 2012-07-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-20
    相关资源
    最近更新 更多