如果我理解正确的话,从C++17开始,这段代码现在要求不进行任何复制:
Foo myfunc(void) {
return Foo();
}
auto foo = myfunc(); // no copy
对于函数参数也是如此吗?在以下代码中,副本是否会被优化掉?
Foo myfunc(Foo foo) {
return foo;
}
auto foo = myfunc(Foo()); // will there be copies?
如果我理解正确的话,从C++17开始,这段代码现在要求不进行任何复制:
Foo myfunc(void) {
return Foo();
}
auto foo = myfunc(); // no copy
对于函数参数也是如此吗?在以下代码中,副本是否会被优化掉?
Foo myfunc(Foo foo) {
return foo;
}
auto foo = myfunc(Foo()); // will there be copies?
Foo myfunc(Foo foo) {
return foo;
}
foo
会被移动到myfunc
的prvalue返回值中。 您可以从概念上将其视为“myfunc
返回有关如何制作Foo
的说明”。 如果您的程序“未使用”这些说明,则会自动实例化临时对象并使用这些说明。(顺便说一下,这些说明包括时间旅行条款;构造的时间点仍然在函数内部!)auto foo = myfunc(Foo());
Foo()
是一个 prvalue。它表示“使用 ()
构造函数构造一个 Foo
”。然后用它来构造 myfunc
的参数。没有省略,也没有调用拷贝构造函数或移动构造函数,只有 ()
。
myfunc
中发生了其他事情。
myfunc
返回一个类型为 Foo
的 prvalue。这个 prvalue(也就是构造指令)被用于构造本地变量 auto foo
。()
构造了一个 Foo
,然后将其移动到 auto foo
中。return func_arg;
上下文中使用时,它们会被隐式移动。myFunc
中,foo
从Foo()
(1个默认构造)初始化。这意味着它将被省略(参见点1)。myFunc
返回一个foo
的副本,由于foo
不是prvalue(第二点),因此无法省略。所以,由于foo
是xvalue,会进行一次move操作。但实际返回值是prvalue,因为它是myFunc
中foo
的新实例,并且由于第一点,它被省略了。
void
? - Rakete1111void
?这可能是在我接触C++之前很久的事情了。 - 463035818_is_not_a_numbervoid
- 在 C 中,我记得空和 void 之间有区别(如果我没记错的话,空允许任意数量的参数?),我想我习惯了 :) - Maël Nisonfoo(void)
是必需的,因为在C中,foo()
表示接受任何参数的函数。而在C++中,foo()
表示不带参数的函数,foo(void)
仅用于向后兼容。 - rustyx