返回的本地变量自动xvalues [英] Are returned locals automatically xvalues

查看:146
本文介绍了返回的本地变量自动xvalues的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

从我对此发表的评论继续:

Following on from a comment I made on this:

将std :: vector传递给构造函数和移动语义
std :: move 以下代码,以确保返回的值是xvalue?

passing std::vector to constructor and move semantics Is the std::move necessary in the following code, to ensure that the returned value is a xvalue?

std::vector<string> buildVector()
{
  std::vector<string> local;

  // .... build a vector

  return std::move(local);
}

这是我的理解,这是必需的。我经常看到这个用于从函数返回 std :: unique_ptr ,但GManNickG做了以下评论:

It is my understanding that this is required. I have often seen this used when returning a std::unique_ptr from a function, however GManNickG made the following comment:

我的理解是,在返回语句中,所有局部变量都是自动xvalues(过期值)并被移动,但我不确定这是否仅适用于返回的对象本身。所以OP应该去把它放在那里,直到我更有信心,它不应该是。 :)

It is my understanding that in a return statement all local variables are automatically xvalues (expiring values) and will be moved, but I'm unsure if that only applies to the returned object itself. So OP should go ahead and put that in there until I'm more confident it shouldn't have to be. :)

任何人都可以澄清是否需要 std :: move

Can anyone clarify if the std::move is necessary?

行为编译器是否依赖?

Is the behaviour compiler dependent?

推荐答案

您可以保证 local 在这个情况下。通常编译器会执行返回值优化,虽然在这之前甚至成为一个问题,你可能根本看不到任何实际的移动,因为 local 对象将被直接构造

You're guaranteed that local will be returned as an rvalue in this situation. Usually compilers would perform return-value optimization though before this even becomes an issue, and you probably wouldn't see any actual move at all, since the local object would be constructed directly at the call site.

在6.6.3 [返回语句](2)中的相关注意

A relevant Note in 6.6.3 ["The return statement"] (2):


与返回语句相关联的复制或移动操作可能被省略或被视为右值,用于在选择一个构造函数(12.8)。

A copy or move operation associated with a return statement may be elided or considered as an rvalue for the purpose of overload resolution in selecting a constructor (12.8).

为了说明,这就是说返回的对象可以从本地对象即使在实践中RVO将完全跳过此步骤)。标准的规范部分是12.8 [复制和移动类对象](31,32),对复制检测和右值(感谢@Mankarse!)。

To clarify, this is to say that the returned object can be move-constructed from the local object (even though in practice RVO will skip this step entirely). The normative part of the standard is 12.8 ["Copying and moving class objects"] (31, 32), on copy elision and rvalues (thanks @Mankarse!).

这是一个愚蠢的例子:

#include <utility>

struct Foo
{
    Foo()            = default;
    Foo(Foo const &) = delete;
    Foo(Foo &&)      = default;
};

Foo f(Foo & x)
{
    Foo y;

    // return x;         // error: use of deleted function ‘Foo::Foo(const Foo&)’
    return std::move(x); // OK
    return std::move(y); // OK
    return y;            // OK (!!)
}

与返回实际的右值引用进行对比:

Contrast this with returning an actual rvalue reference:

Foo && g()
{
    Foo y;
    // return y;         // error: cannot bind ‘Foo’ lvalue to ‘Foo&&’
    return std::move(y); // OK type-wise (but undefined behaviour, thanks @GMNG)
}

这篇关于返回的本地变量自动xvalues的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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