如果需要转换,我可以在读取参数的同时将其移动到另一个参数吗?
Can I read from a parameter at the same time as moving it into another parameter if a conversion is required?
假设我有代码:
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
移动构造,因此它将窃取其内脏。 这意味着当您去初始化first
时a
处于有效但不确定的状态。 在此之后使用first
将是未定义的行为。 现在,如果顺序颠倒了,您可以没问题,但由于未指定顺序,因此无法保证任何一致的行为。
你是对的,std::move
实际上并没有移动任何东西,但使用传递给std::move
的对象初始化second
将导致second
使用它的移动构造函数,这实际上会移动a
。
相关文章:
- MSVC将仅移动结构参数解释为指针
- 如果需要转换,我可以在读取参数的同时将其移动到另一个参数吗?
- 使用移动语义:右值引用作为方法参数
- 为什么参数在构造 std::thread 时移动两次
- 移动类的成员作为常量引用参数传递
- 当变量和参数名称匹配时,移动语义构造失败
- 使用 std::move 将参数传递给函数,如果该参数声明为按值传递或使用移动操作数 &&,是否有区别?
- 移动构造函数中的默认参数
- 将参数传递给构造函数和成员函数时移动或复制
- 从函数返回元组时,将复制元组的参数,而不是移动元组参数
- C++具有移动语义的可变参数工厂会导致运行时崩溃
- 覆盖Qt的鼠标按下事件中断移动事件参数
- 在简单地移动参数时使用函数模板参数的优点
- 如果没有带有函数签名的 rvalue 参数,是否会执行 C++ 11 中的移动语义?
- x64 函数调用参数推送/移动顺序 (MSVC)
- 复制文件成功,移动文件失败,参数相同 - C++
- 从从可调用参数创建的线程对象参数移动构造 C++11 线程
- 将std::enable_if从参数移动到模板参数
- 将所有参数移动到 lambda
- 将参数移动到std::线程中