- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
在 comment to another question 中Jonathan Wakely 回应我的声明:
You never need explicit move for a local variable function return value. It's implicit move there
->
... never say never ... You need an explicit move if the local variable is not the same type as the return type, e.g.
std::unique_ptr<base>
, but if the types are the same it will move if possible ...
f() { auto p = std::make_unique<derived>(); p->foo(); return p; }
所以有时我们可能不得不在返回时 move 一个局部变量。
例子
std::unique_ptr<base> f() {
auto p = std::make_unique<derived>();
p->foo();
return p;
}
很好,因为它给出了 compilation error
> prog.cpp:10:14: error: cannot convert ‘p’ from type
> ‘std::unique_ptr<derived>’ to type ‘std::unique_ptr<derived>&&’
但我想知道一般情况下是否有很好的机会检测到这一点 - 这是语言规则或unique_ptr
的限制吗? ??
最佳答案
更新:
现代编译器版本不需要显式 move 。
核心 DR 1579更改了规则,以便即使类型不同,返回值也将被视为右值。 GCC 5 为 C++11 和 C++14 实现了新规则。
原答案:
这不是 unique_ptr
的限制,而是语言的限制,同样的限制适用于任何调用带有右值引用的转换构造函数的 return
语句:
struct U { };
struct T {
T(U&&) { }
};
T f() {
U u;
return u; // error, cannot bind lvalue to U&&
}
这不会编译,因为 [class.copy]/32 说:
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.
这意味着 return
语句中的表达式只有在符合复制/move 省略(又名 NRVO)条件时才能被视为右值,但这限制性太强,因为这意味着它只适用当类型完全相同时,即使变量总是超出范围,所以总是将 is 视为右值是合理的(从技术上讲,它是一个 xvalue,一个 expiring 值。)
这是最近 suggested由 Richard Smith (以前是 Xeo),我认为这是一个非常好的主意。
关于c++ - return 语句何时需要显式 move ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17481018/
我是一名优秀的程序员,十分优秀!