【发布时间】:2018-12-12 06:22:43
【问题描述】:
我有以下功能:
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,不会发生复制/移动省略。
在这两种情况下,我都有相同的输出:
"default constructor"
"move constructor"
为什么在情况 2 中移动构造函数只调用一次?我本来希望为函数的返回值调用一次,然后为初始化 someObject 变量调用一次。
更新:更清楚地说:输出用于调试构建。对于发布版本,我只有“默认构造函数”,由于复制/移动省略,这对我来说似乎很清楚。我想了解调试版本的不同输出。
【问题讨论】:
-
你是用 C++17 构建的吗?如果 NRVO 启用,您根本不会看到移动 c'tor 调用。
-
这是一个没有根据的假设。即使在调试版本中,编译器仍然会进行很多优化。主要是因为它们不会影响可调试性。
-
这并不奇怪。我询问了您的构建选项(一种语言标准)是有原因的。编译器可以并且将进行的优化类型取决于很多 因素。你不能把它简化为 debug vs release。
-
老实说,如果调试版本决定在发布版本上关闭复制省略,我会感到非常惊讶。移动和复制构造函数可能会产生副作用,因此可能会导致代码行为不同。
-
g++ -std=c++14 -fno-elide-constructors给我default+move+move。切换到c++17会得到default+move。删除-fno-elide-constructors导致default仅适用于 c++14 和 17。
标签: c++ constructor move