示例:
Foo return_a_foo()
{
const auto a_foo = make_a_foo();
//Work with, but do not mutate a_foo...
return a_foo;
}
如果编译器不能使用RVO,我至少会期望它尝试移动a_foo。但是,a_foo是const(但仍然要超出范围)。它是否在标准的任何地方都说100%保证不移动(无赖)或者是实现定义?
答案 0 :(得分:4)
仍然可以移动按值返回的const对象吗?
有些人会惊讶地得知答案是“有时是的”。
但是,您必须为它们提供更多构造函数才能启用此功能。您还必须要么成员mutable
,要么手动处理const-move-construction。
证明:
#include <iostream>
#include <memory>
struct Foo
{
Foo() { std::cout << "default c'tor\n"; }
Foo(Foo const&&) { std::cout << "Foo const&&\n"; }
Foo(Foo &&) { std::cout << "Foo &&\n"; }
Foo(Foo const&) { std::cout << "Foo const&\n"; }
Foo(Foo &) { std::cout << "Foo &\n"; }
};
const Foo make_a_foo()
{
auto p = std::make_unique<const Foo>();
return std::move(*p);
}
const Foo return_a_foo()
{
const auto a_foo = make_a_foo();
//Work with, but do not mutate a_foo...
return a_foo;
}
int main()
{
auto f = return_a_foo();
}
示例输出:
default c'tor
Foo const&&
答案 1 :(得分:2)
不,const T
无法绑定到非常量T&&
,因此a_foo
无法移动。
您的函数返回非const Foo
,因此a_foo
将被复制到返回值。然后可以移动返回值,因为它是非常量的。请参阅this example。
实际上,所有这些副本和动作都可能被删除。