c++ - 编译器如何知道 move 局部变量?

标签 c++ c++11 move-semantics

我很好奇这个功能究竟是如何工作的。考虑类似的事情

std::unique_ptr<int> f() { std::unique_ptr<int> lval(nullptr); return lval; }

此代码即使对于仅 move 类型也能很好地编译,因为编译器会隐式 move 它。但从逻辑上讲,对于任何返回表达式,确定结果是否引用局部变量将解决暂停问题——如果编译器简单地将所有局部变量视为返回表达式中的右值,那么这将是有问题的,因为变量可以在那个表达式中多次引用。即使本地只有一个直接引用,您也无法证明它没有其他间接别名。

那么编译器如何知道何时从返回表达式 move ?

最佳答案

有一个简单的规则:如果满足复制省略的条件(除了变量可能是函数参数),则视为右值。如果失败,则视为左值。否则,视为左值。

§12.8 [class.copy] p32

When the criteria for elision of a copy operation are met or would be met save for the fact that the source object is a function parameter, and the object to be copied is designated by an lvalue, overload resolution to select the constructor for the copy is first performed as if the object were designated by an rvalue. If overload resolution fails, or if the type of the first parameter of the selected constructor is not an rvalue reference to the object’s type (possibly cv-qualified), overload resolution is performed again, considering the object as an lvalue. [ Note: This two-stage overload resolution must be performed regardless of whether copy elision will occur. It determines the constructor to be called if elision is not performed, and the selected constructor must be accessible even if the call is elided. —end note ]

例子:

template<class T>
T f(T v, bool b){
  T t;
  if(b)
    return t; // automatic move
  return v; // automatic move, even though it's a parameter
}

并不是说我个人同意该规则,因为以下代码中没有自动 move :

template<class T>
struct X{
  T v;
};

template<class T>
T f(){
  X<T> x;
  return x.v; // no automatic move, needs 'std::move'
}

另见 this question of mine .

关于c++ - 编译器如何知道 move 局部变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11492948/

相关文章:

c++ - move 语义如何在 vector 重定位中起作用?

c++ - gcov 函数未执行,但行已执行

c++ - MFC CDialog 不显示

c++ - 编译器能否从正则表达式中计算出 DFA?

c++ - 使用 std::mutex 关闭头文件的 clr 选项

c++ - boost 无法使用 gcc move scoped_lock

c++11 - 用户声明的隐式声明的 move 赋值运算符意味着什么?

c++ - 将两个变体与 boost static_visitor 进行比较

c++ - 为C++程序编写MASM函数

c++ - 部分聚合初始化和非静态数据成员初始化器