假设我有这个功能:
template <class A>
inline A f()
{
A const r(/* a very complex and expensive construction */);
return r;
}声明r const是个好主意,因为const变量不能移动?注意,返回的值不是const。我所担心的是,r确实是const,但宣布它为const可能不是一个好主意。然而,限定符应该有助于编译器生成更好的代码。
发布于 2013-08-26 02:45:40
作为在此演示,NRVO继承了行return r;所隐含的r的副本。
#include <iostream>
struct A {
const char* name;
A( const char* name_ ):name(name_) { std::cout << "created " << name << "\n"; }
A(A const&){ std::cout << "copied " << name << "\n"; }
A(A &&){ std::cout << "moved " << name << "\n"; }
};
A f() {
std::cout << "start of f()\n";
A const r("bob");
std::cout << "body of f()\n";
return r;
}
int main() {
A x = f();
}main中的副本也被删除。
如果以其他方式阻止NRVO和RVO (例如在与GCC一起编译时使用标志-fno-elide-constructors ),则const可以使您的对象被复制而不是moved。
#include <iostream>
struct A {
const char* name;
A( const char* name_ ):name(name_) { std::cout << "created " << name << "\n"; }
//A(A const&){ std::cout << "copied " << name << "\n"; }
A(A &&){ std::cout << "moved " << name << "\n"; }
};
A f() {
std::cout << "start of f()\n";
A const r("bob");
std::cout << "body of f()\n";
return r;
}
int main() {
A x = f();
}代码不再编译。虽然只要发生NRVO,复制构造函数就不会执行,但const局部变量需要它的存在。
现在,NRVO需要一些东西,例如沿着所述函数的每个执行路径返回的单个变量:如果您曾经“中止”并执行return A(),则NRVO将被阻塞,并且您的const局部变量突然强制在所有返回站点上复制。
发布于 2013-08-26 02:54:42
如果class A在您的控制下,并且希望通过移动返回const对象,则可以这样做
mutable bool resources_were_stolen = false;并在const移动构造函数中将其设置为true。
A(const A&& other) { ...; other.resources_were_stolen = true; }
~A() { if (!resources_were_stolen) ... }实际上,使用对象在构造和破坏过程中丢失const-ness这一事实,析构函数可能会变成const。
https://stackoverflow.com/questions/18435820
复制相似问题