example:
比如以下函数,就会编译时会返回值优化
class A
{
};
A function()
{
return A();
}
为了简单讲述,考虑下面的情形,将一个函数的返回值赋值给一个变量。
T t = f();
如果要优化这种拷贝,一个共性的想法是,允许编译器使用t的内存空间(这个空间在函数f之外)
来直接构造
函数里面将要生成的值。 这样就不需要copy 这个动作了。
为什么会返回值优化?
返回值优化适用于优化 值拷贝的情况。
提升速度,不用发生拷贝对象等事情。
分为
- RVO (return value optimization)
- NRVO (named return value optimization)
返回值优化 优先级
return value optimization > move > normal
RVO
例:
T f()
{
...
return T(constructor arguments);
}
at call site
T t = f();
理论上来说,总共有3个对象被创建
- 在 f 内,构造的对象,是一个临时对象
- 另外一个临时对象 f , return 的对象,是从 f 中copy的
- 外部的 t 对象, 从上面的对象copy
RVO 就是让编译器移除两个临时对象,直接让相关对象在t的内存上初始化。
rule: 只要是 跟着return 后面创建的对象,都会被执行return value optimization
NRVO
see link
NRVO
更多例子
NRVO
class A
{
public:
int value;
A(){};
A(A&)
{
cout<<"copy constructor" <<endl;
}
A& operator=(A& a) // copy
{
cout<<"copy assignment operator" <<endl;
if(&a == this)
return *this;
this->value = value;
return *this;
}
A& operator=(A&& a) // move
{
cout << "move assignment operator" << endl;
if(&a == this)
return *this;
this->value = value;
return *this;
}
};
A f()
{
A a;
return a;
};
A f_1()
{
return A(); // return the value
};
int main()
{
// NRVO
A a = f();
// not happen
A a;
a = f();
// RVO
A a;
a = f_1();
return 0;
}