为什么函数中变量的最后一个赋值不能被视为移动?
Why can't the last assignment from a variable in a function be treated as a move?
在如下代码中:
class X {
X(const X&) {
// ...
}
X(const X&&) {
// ...
}
// ...
};
void f() {
X a;
// ...
X b = a;
// ... code that doesn't use a
}
我的理解是最后一个语句调用复制构造函数而不是移动构造函数。假设a
在f()
中不再使用,编译器可以自动优化此语句以使用move构造函数代替吗?
注:我知道std::move()
,但我问的是自动移动
您需要编写一个规范,以某种方式正确处理
void f() {
X a;
g(a); // stash a reference to a somewhere
X b = a; // can't move from a!
g2(); // use the reference stored by g
}
对于安全的移动,您需要证明后续代码,包括它调用的所有函数,不直接或间接访问a
,这在一般情况下是不可能的,因为这些函数的定义可能对编译器不可用(例如,在不同的翻译单元中)。
编译器很难/不可能知道a
是未引用的,除非在一些平凡的场景中。任何外部函数都可以保存指向a
的指针或引用,并且任何外部函数都可以依赖于该指针的内容。
在不涉及外部函数的情况下,我猜优化是可能的。
如果没有更严格的分析,优化将不是完全安全的。例如,一个局部对象可能已经用a
的地址进行了初始化,并在销毁时对它做了一些操作,这将发生在最后一条语句X b = a;
之后。
相关文章:
- 如果唯一指针是捕获的值,为什么它不能在 lambda 内移动?
- 为什么我不能将元素移动到不可复制的向量中?
- std::仅移动类型列表:不能在 VC++ 中放入 std::vector
- Qt - 拖动移动 q图形项不能很好地工作
- 为什么这些变量不能移动?
- 为什么 std::ostream 不能移动?
- 我不能在不使用指针的情况下返回 2d 数组!我正在制作一个井字游戏类型游戏,这是我的向上移动功能
- 如果成员具有非平凡的noexcept赋值运算符,则默认的移动赋值不能显式为noexcept
- 为什么 C++11 不能将不可复制的函子移动到 std::函数?
- 为什么我不能移动 std::ofstream?
- 在将对象移动到另一个线程后,不能简单地删除该对象
- 为什么我的 switch 语句不能移动到下一个案例?
- 为什么当一个成员不能移动时,整个封闭类就不能移动
- 不能移动集合迭代器
- 可以随意移动,但不能随意复制
- 在c++中,如果不能被5整除,则移动到while循环
- 为什么对象 (.obj) 文件不能跨平台移动?
- 不能使用boost object_pool构造移动构造函数来构造对象
- 为什么函数中变量的最后一个赋值不能被视为移动?
- 为什么在c++ 11中所有的迭代器/迭代器适配器都不能移动?