按值返回时值参数是否隐式移动?
考虑以下函数:
Foo foo(Foo x)
{
return x;
}
return x
会调用复制构造函数还是移动构造函数吗? (让我们把 NRVO 放在一边。)
为了进行调查,我编写了一个简单的 Foo 类,它只能移动但不可复制:
struct Foo
{
Foo() = default;
Foo(const Foo&) = delete;
Foo(Foo&&) = default;
};
如果在按值返回值参数时调用移动构造函数,那么一切都应该没问题。但当前的 g++ 编译器抱怨 return x
并显示以下错误消息:
error: deleted function 'Foo::Foo(const Foo&)'
如果我将 return x
替换为 return std::move(x)
,一切都很好。由此我得出的结论是,如果需要的话,必须明确地从值参数中移动。 g++ 的行为是否符合规范?
Consider the following function:
Foo foo(Foo x)
{
return x;
}
Will return x
invoke the copy constructor or the move constructor? (Let's leave NRVO aside here.)
To investigate, I wrote a simple Foo
class that is only movable but not copyable:
struct Foo
{
Foo() = default;
Foo(const Foo&) = delete;
Foo(Foo&&) = default;
};
If the move constructor were invoked when returning value parameters by value, all should be fine. But the current g++ compiler complains about return x
with the following error message:
error: deleted function 'Foo::Foo(const Foo&)'
If I replace return x
with return std::move(x)
, everything is fine. From this I conclude that moving from value parameters must be done explicitly if desired. Is g++'s behavior conforming or not?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果 Foo 有移动向量,则应选择它。
函数参数在 return 语句中明确排除在复制省略之外(FDIS §12.9p31,第一个项目符号):
但是,下一段明确重新考虑移动因素:
(两段引文中的重点都是我的。)
If there is a move ctor for Foo, it should be selected.
Function parameters are explicitly excluded from copy elision in return statements (FDIS §12.9p31, first bullet):
However, the next paragraph explicitly brings move ctors back into consideration:
(Emphasis is mine in both quotes.)
这是有效的代码 - G++ 的行为不符合规定。 MSVC10 确实支持此行为。
This is valid code- G++'s behaviour is non-conformant. MSVC10 does support this behaviour.