首页 > 解决方案 > 为什么在按值返回时创建临时对象而不是在将值传递给函数参数时创建临时对象

问题描述

原型:

class A;
A func(A obj2)
{
  return obj2;
};

int main()
{
  A obj1;
  A obj3 = func(obj1);

  return 0;
}

通过值将参数传递给函数时,它从调用函数的堆栈变量(obj1)复制到被调用函数的堆栈变量(obj2),没有任何临时对象。那么为什么在从函数中按值返回时不能以相同的方式。即 obj2 可以直接复制到 obj3 而无需创建任何临时对象(此处忽略 RVO)。

是因为 func() 可以在不收集其返回值的情况下被调用吗?还是幕后还有其他逻辑?

标签: c++

解决方案


在 C++17 之前,一切照常工作,因为那是语言设定的模型。prvalue 代表一个临时对象。如果一个函数要返回一个纯右值,那么该return语句必须使用给定的表达式创建该临时对象。这必然涉及复制/移动操作。将纯右值分配给正在初始化的对象将执行从临时对象到新对象的复制/移动。

请注意,C++17通过本质上重新定义纯右值来提供有保证的省略。它不再是一个对象;它是一个对象的初始化器。哪个对象被初始化取决于prvalue的使用方式。该return语句不会创建临时的;它的表达式简单地定义了初始化器将是什么。如果您使用纯右值来初始化纯右值类型的对象,那么它会初始化该对象。如果您尝试初始化某个其他类型的对象,则会初始化纯右值类型的临时对象,并通过该临时对象初始化另一个对象。


推荐阅读