如果需要转换,我可以在读取参数的同时将其移动到另一个参数吗?

Can I read from a parameter at the same time as moving it into another parameter if a conversion is required?

本文关键字:参数 移动 另一个 转换 我可以 读取 如果      更新时间:2023-10-16

假设我有代码:

struct A {int val, string name};
A a{5, "Hello"};
fn(a.val, std::move(a));

现在看起来我正在从a读取,并且在同一行上从a移动,这看起来很糟糕,因为参数排序通常是未定义的。但是,由于std::move只是一个应该没问题的演员表 - 所以我实际上并没有从值move中读取。

但是,如果fn实际上按获取第二个参数会发生什么:

fn(int first, A second);

在这种情况下,必须从移出值a构造新A。在我的第一个示例中,这会开始导致问题吗?我假设参数second的构造函数可以在读取第一个参数a.val之前调用?

您将遇到的问题是 [expr.call]/8

后缀表达式在表达式列表中的每个表达式和任何默认参数之前排序。参数的初始化,包括每个关联的值计算和副作用,相对于任何其他参数的初始化都是不确定的。

强调我的

因此,接下来可能发生的情况是首先初始化second,它将从a移动构造,因此它将窃取其内脏。 这意味着当您去初始化firsta处于有效但不确定的状态。 在此之后使用first将是未定义的行为。 现在,如果顺序颠倒了,您可以没问题,但由于未指定顺序,因此无法保证任何一致的行为。

你是对的,std::move实际上并没有移动任何东西,但使用传递给std::move的对象初始化second将导致second使用它的移动构造函数,这实际上会移动a