gpt4 book ai didi

c++ - 为什么 move 构造函数只被调用一次?

转载 作者:行者123 更新时间:2023-11-30 04:53:57 25 4
gpt4 key购买 nike

我有以下功能:

SomeClass func()
{
SomeClass someObject;
someObject.mutate("some text");
return someObject;
}

以及以下两种情况:

1

int main()
{
func();
return 0;
}

2

int main()
{
SomeClass someObject = func();
return 0;
}

我关闭了 NRVO,没有发生复制/move 省略。

在这两种情况下,我都有相同的输出:

"default constructor"
"move constructor"

为什么 move 构造函数在情况 2 中只被调用一次?我原以为会被调用一次以获得函数的返回值,然后被调用一次以初始化 someObject 变量。

更新:更清楚:输出用于调试构建。对于发布版本,我只有“默认构造函数”,由于复制/move 省略,这对我来说似乎很清楚。我想了解调试版本的不同输出。

最佳答案

这是由于 C++17 中的复制省略。来自 cppreference :

Under the following circumstances, the compilers are permitted, but not required to omit the copy and move (since C++11) construction of class objects even if the copy/move (since C++11) constructor and the destructor have observable side-effects.
[...]
In the initialization of an object, when the source object is a nameless temporary and is of the same class type (ignoring cv-qualification) as the target object. When the nameless temporary is the operand of a return statement, this variant of copy elision is known as RVO, "return value optimization".
This optimization is mandatory; see above. (since C++17)

另见复制初始化。同样来自 cppreference :

The effects of copy initialization are:
First, if T is a class type and the initializer is a prvalue expression whose cv-unqualified type is the same class as T, the initializer expression itself, rather than a temporary materialized from it, is used to initialize the destination object: see copy elision (since C++17)

请注意,这不是 NRVO(命名 返回值优化)。这是 RVO。

在 C++14 中,如果您不希望优化不会发生(参见 -fno-elide-constructors)。
Demo (使用 GCC,但 Clang 产生相同的结果)

在 C++17 中,它是强制性的,所以它确实发生了。
Demo (同样,GCC 但 Clang 同意)

关于c++ - 为什么 move 构造函数只被调用一次?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53737194/

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