return语句何时需要显式移动
When is explicit move needed for a return statement?
在对另一个问题的评论中,Jonathan Wakely回应了我的陈述:
局部变量函数返回不需要显式移动价值这是隐含的移动到
->
永远不要说永远。。。如果局部变量与返回类型不同,例如
std::unique_ptr<base> f() { auto p = std::make_unique<derived>(); p->foo(); return p; }
,但是如果类型相同,它会在可能的情况下移动。。。
因此,有时我们可能不得不在返回时移动局部变量。
示例
std::unique_ptr<base> f() {
auto p = std::make_unique<derived>();
p->foo();
return p;
}
很好,因为它给出了一个编译错误
> prog.cpp:10:14: error: cannot convert ‘p’ from type
> ‘std::unique_ptr<derived>’ to type ‘std::unique_ptr<derived>&&’
但我想知道是否有很好的机会在一般情况下检测到这一点——这是语言规则的限制还是unique_ptr
的限制??
更新:
在现代编译器版本中不应该需要显式移动。
Core 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说:
当满足或将满足省略复制操作的标准时,除非源对象是函数参数,并且要复制的对象是由左值指定的,否则首先执行重载解析以选择复制的构造函数,就好像对象是由右值指定的一样。
这意味着CCD_ 5语句中的表达式只有在符合复制/移动省略(又名NRVO)条件时才能被视为右值,即使变量总是超出范围,所以总是将is视为右值是合理的(从技术上讲,是一个xvalue,一个过期值。)
这是Richard Smith最近提出的(之前也是Xeo提出的),我认为这是一个非常好的主意。
- 将对象移动到std::shared_ptr
- 何时在引用或唯一指针上使用移动语义
- 我的简单if-else语句是如何无法访问的代码
- 有一个打印语句的函数是一种糟糕的编程实践吗
- 线程,如果else语句,都是错误的上下文切换后,会发生什么
- 为什么是0;C++中的有效语句
- 如何从具有移动语义的类对象中生成共享指针
- 将shared_ptr移动到<StructA>shared_ptr<变体<结构A、结构 B>>
- C / C++ 移位/偏移/向左或向右移动位图?
- Insert函数不适用于2 if语句C++
- C++:我应该在 return 语句中显式使用 std::move() 来强制移动吗?
- 为什么结构化绑定禁用RVO和移动返回语句
- 如何在COUT语句中使用移动运算符
- C++11 是否保证 return 语句中的局部变量将被移动而不是复制?
- If/Else 语句在 2D 数组中移动时出现问题
- 复制 ELISION:在 return 语句中使用三元表达式时未调用移动构造函数
- 为什么我的 switch 语句不能移动到下一个案例?
- 什么样的参数可以在返回语句中自动移动
- return语句何时需要显式移动
- 如果函数调用是返回语句,编译器可以自动移动函数参数吗?