c++ 调用带大括号的构造函数

hrirmatl  于 2023-02-06  发布在  其他
关注(0)|答案(3)|浏览(206)

关于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};那样,用花括号调用构造函数,它既不是初始化列表,也不是统一初始化,这是什么东西?

yqlxgs2m

yqlxgs2m1#

它既不是初始化器列表,也不是统一初始化。这是什么东西?
你的前提是错误的,它是统一初始化,用标准术语来说,就是 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.
dpiehjr4

dpiehjr42#

这只是C++11语法。你可以用花括号初始化对象的构造函数。你只需要记住如果类型有initializer_list构造函数,那么那个构造函数优先。

g0czyy6m

g0czyy6m3#

此外,大括号构造函数不允许收缩,类似于大括号初始化。
让我们看一下这个简单的构造函数如何获取和打印一个整数值:

class Test {
public:
        Test(int i) {
                std::cout << i << std::endl;
        }
};

Test test(3.14);编译并输出缩小的3时,
Test test{3.14};甚至无法编译:

error: narrowing conversion of ‘3.1400000000000001e+0’ from ‘double’ to ‘int’ [-Wnarrowing]
   11 |  Test test{3.14};
      |                ^

相关问题