返回本地对象是否需要移动语义? [英] Does returning a local object require move semantics?

查看:52
本文介绍了返回本地对象是否需要移动语义?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

按值返回本地对象时,C ++编译器可以利用移动语义来优化不必要的副本(复制省略)。

可以优化表示,如果不满足适当的条件,则该行为应回退到基于copy的默认按值返回语义。

因此,据我所知,

When returning a local object by value, C++ compilers may optimize out unnecessary copies (copy elision) by taking advantage of the move semantics.
"may optimize" implies that if proper conditions are not met, the behavior should fall back to the default return by value semantics, based on copy.
Thus, as I understand it, it is always valid to return a copyable object by value.

但是编译器(clang和gcc)似乎与我的解释不一致,如下面的MWE所示。

But compilers (clang and gcc) do not seem to agree with my interpretation, as shown by the MWE below.

class Foo {
public:
    Foo();
    Foo(const Foo&);
    Foo(Foo&&) = delete;
}

Foo f() { return Foo(); }  // error: call to explicitly deleted constructor of 'Foo'
Foo g() { Foo a; return a; }  // gcc complains, clang is fine
Foo x = g();  // error: call to explicitly deleted constructor of 'A'

Q1:按值返回是否需要对象

问题2:如果没有,gcc和clang是否在我的MWE上出现异常,或者我还缺少其他东西?

Q1: Does return by value requires object to be movable?
Q2: If not, do gcc and clang misbehave on my MWE or am I missing something else?

推荐答案

您只是在满足重载解析的预期行为: Foo()是一个右值,因此重载解析会找到构造函数 Foo (Foo&&)作为最佳匹配。由于该重载已删除,因此您的程序格式错误。此外,有一条特殊规则说 Foo a;返回a; 还将执行重载解析,就好像 a 首先是右值一样。 (该规则基本上适用于return语句可以进行复制省略的情况。)

You are simply meeting the intended behaviour of overload resolution: Foo() is an rvalue, so overload resolution finds the constructor Foo(Foo&&) as the best match. Since that overload is deleted, your program is ill-formed. Moreover, there's a special rule that says Foo a; return a; will also perform overload resolution as if a was an rvalue first. (The rule applies essentially whenever the the return statement is eligible for copy elision.)

这一切都按预期进行。是您删除了重载,因此您明确要求禁止这种构造。

This is all working as intended. It was you who deleted the overload, so you requested expressly that such constructions be forbidden.

请注意,真实的代码通常不会遇到此障碍,因为当您声明一个复制构造函数时,您的类将完全没有任何移动构造函数。但是您却大胆地说:不,实际上我要做想要一个move构造函数,并且如果有人尝试使用它,我希望它是一个错误。

Note that "real" code doesn't usually meet this obstacle, since as soon as you declare a copy constructor, your class will not have any move constructors at all. But you went out of your way to say, "no, actually I do want a move constructor, and I want it to be an error if anyone attempts to use it".

这篇关于返回本地对象是否需要移动语义?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆