我知道在以下情况下编译器可以自由移动 - 构造返回值makeA
(但也可以自由地删除副本或完全移动):
struct A
{
A(A&);
A(A&&);
};
A makeA()
{
A localA;
return localA;
}
Run Code Online (Sandbox Code Playgroud)
我想知道是否允许编译器通过rvalue引用A
从类型的本地对象构造类型的对象(B
如果它是在return语句中构造的).换句话说,在下面的例子中,是否允许编译器A
为返回值选择构造函数4?
struct B { };
struct A {
A(A&); // (1)
A(A&&); // (2)
A(B&); // (3)
A(B&&); // (4)
};
A makeA()
{
B localB;
return localB;
}
Run Code Online (Sandbox Code Playgroud)
我问这个是因为在我看来,允许类型的本地对象A
在return语句中被视为rvalue 的相同逻辑也应该允许任何类型的本地被视为rvalue,但我找不到任何这种例子或问题.
在对另一个问题的评论中, 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;
}
Run Code Online (Sandbox Code Playgroud)
很好,因为它给出了编译错误
> prog.cpp:10:14: error: cannot convert ‘p’ from type
> ‘std::unique_ptr<derived>’ to type ‘std::unique_ptr<derived>&&’
Run Code Online (Sandbox Code Playgroud)
但我想知道是否有一个很好的机会来检测这一般 - 这是这里的语言规则或unique_ptr
??