为什么函数中变量的最后一个赋值不能被视为一个移动?

时间:2015-06-09 20:01:34

标签: c++ c++11

在这样的代码中:

class X {
  X(const X&) {
    // ...
  }

  X(const X&&) {
    // ...
  }

  // ...
};

void f() {
  X a;
  // ...
  X b = a;
  // ... code that doesn't use a
}

我的理解是最后一个语句调用复制构造函数而不是移动构造函数。假设在a中再也没有使用f(),编译器是否可以自动优化此语句以使用移动构造函数?

P.S。我知道std::move(),但我问的是自动移动。

3 个答案:

答案 0 :(得分:4)

您需要编写一个以某种方式正确处理的规范

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,这在一般情况下是不可能的,因为编译器可能无法使用这些函数的定义(例如,在不同的翻译单元中)。

答案 1 :(得分:0)

编译器很难/不可能知道除了琐碎的场景之外a是未引用的。任何外部函数都可以保存指向a的指针或引用,任何外部函数都可以依赖于所述指针的内容。

在没有涉及外部功能的情况下,我想可以进行优化。

答案 2 :(得分:0)

如果没有更严格的分析,优化就不会完全安全。例如,本地对象可能已使用a的地址进行初始化,并在销毁时对其执行某些操作,这将在最后一个语句X b = a;之后发生。