从C ++ 17开始,复制省略是强制性的,它改变了prvalues的工作方式。现在,当返回一个临时变量(我知道它不是一个临时变量,只是一个初始化程序)时,该初始化程序将沿调用链传递,并用于初始化用于存储函数结果的对象。
我的问题是,如何将初始化程序沿函数调用链传递?还是我对它的工作方式有误?
例如:
struct Foo
{
// some impl...
}
Foo Bar()
{
return Foo{}; // temporary not constructed, prvalue passed up
}
int main()
{
Foo foo = Bar(); // equivalent to Foo foo;
}
答案 0 :(得分:3)
诀窍在于调用约定。
本质上,返回值作为指针传递给函数要构造返回值的位置。
这一直传递到最内部的函数调用,并且那里的prvalue直接在最终对象位置构造结果。
当添加有保证的省略时,标准委员会仔细检查了每个主要编译器已经在使用这种调用约定,并且不会发生技术障碍或ABI中断。
以上内容只包含了一些小谎言,但是作为一个假设故事使结果似乎合理,并且在大多数情况下都是真实的。
重要的谎言是在描述C ++标准的抽象机中发生的事情,没有传递“返回对象位置的指针”;相反,prvalue必须以某种方式构造最终对象。 如何无关紧要。
因此,只要指针不存在,编译器仍可以按指针存在的方式构造对象。 (例如,返回寄存器中的某些类型的对象;对于那些不占用地址的琐碎可复制的聚合类型,则无法观察其何时(有时是否到达)其最终位置)。