gpt4 book ai didi

c++ - 为什么按值参数从 NRVO 中排除?

转载 作者:IT老高 更新时间:2023-10-28 12:31:21 24 4
gpt4 key购买 nike

想象一下:

S f(S a) {
return a;
}

为什么不允许别名a和返回值槽?

S s = f(t);
S s = t; // can't generally transform it to this :(

如果 S 的复制构造函数有副作用,规范不允许这种转换。相反,它至少需要两份拷贝(一份从 ta,一份从 a 到返回值,另一份从返回s 的值,只有最后一个可以省略。请注意,我在上面写了 = t 来表示 t 拷贝的事实到 f 的 a,唯一的拷贝在存在移动/复制构造函数的副作用的情况下仍然是强制性的)。

这是为什么呢?

最佳答案

这就是为什么复制省略对参数没有意义。这实际上是关于在编译器级别实现概念的。

复制省略的工作原理是在原地构造返回值。该值不会被复制出来;它是直接在其预期目的地创建的。为预期输出提供空间的是调用者,因此最终是调用者为省略提供了可能性。

为了消除拷贝,函数内部需要做的就是在调用者提供的位置构造输出。如果函数可以做到这一点,你会得到复制省略。如果函数不能,那么它将使用一个或多个临时变量来存储中间结果,然后将其复制/移动到调用者提供的位置。它仍然是就地构造的,但输出的构造是通过复制发生的。

因此,特定函数之外的世界不必知道或关心函数是否进行省略。具体来说,函数的调用者不必知道函数是如何实现的。它没有做任何不同的事情。是函数本身决定是否可以省略。

值参数的存储也由调用者提供。当您调用 f(t) 时,调用者会创建 t 的拷贝并将其传递给 f。类似地,如果 S 可以从 int 隐式构造,那么 f(5) 将从5 并将其传递给 f.

这一切都是由调用者完成的。被调用者不知道也不关心它是变量还是临时变量;它只是给了一个堆栈内存(或寄存器或其他任何东西)。

现在请记住:复制省略有效,因为被调用的函数将变量直接构造到输出位置。因此,如果您试图忽略值参数的返回,那么值参数的存储也必须是输出存储本身。但请记住:调用者为参数和输出提供存储。因此,为了省略输出拷贝,调用者必须将参数直接构造到输出中。

为此,现在调用者需要知道它正在调用的函数将忽略返回值,因为如果参数将被返回,它只能将参数直接粘贴到输出中。这在编译器级别通常是不可能的,因为调用者不一定具有函数的实现。如果函数是内联的,那么它也许可以工作。但否则没有。

因此,C++ 委员会并没有考虑到这种可能性。

关于c++ - 为什么按值参数从 NRVO 中排除?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6009278/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com