C++ 按值返回的函数可以返回右值引用吗?

问题描述 投票:0回答:1

我正在阅读右值,并在编译器资源管理器上尝试代码片段时遇到了一些问题。这是一个人为的例子:

class A
{
    public:

    A&& func(A& rhs)
    {
        //return rhs;
        return std::move(rhs); //returning A&&
    }
};

class A
{
    public:

    A func(A& rhs)
    {
        //return rhs;
        return std::move(rhs); //returning A&&
    }
};

我预计这个第二个片段由于返回类型不匹配而无法编译。这里 Func 的返回类型是 A,而它实际返回的是 A&& 礼貌 std::move()。我尝试过最新版本的 gcc、clang 和 msvc。所有人都有同样的行为。有人可以解释一下这是怎么回事吗?

c++ rvalue-reference
1个回答
0
投票

在 C++ 中,当您在对象上使用 std::move 时,您实际上并未将其转换为右值引用 (T&&)。相反,您将其转换为右值,这向编译器发出信号,表明它可以将该对象视为临时对象,并且如果可能的话,从该对象中移动而不是复制。然而,std::move 不会改变底层类型;它只是为编译器提供使用移动语义的提示。

以下是两个示例中发生的情况:

示例 1:A&& func(A& rhs)

在此版本中,函数 func 返回 A&& (对 A 的右值引用)。当您返回 std::move(rhs) 时,您直接返回一个右值引用,它与返回类型 A&& 匹配。这是有道理的,并且会按预期编译。

示例 2:A func(A& rhs)

在这种情况下,函数 func 的返回类型为 A,它是一个值(不是右值引用)。但是,当您返回 std::move(rhs) 时,您仍然将 rhs 转换为右值引用 (A&&)。这就是为什么它仍然可以编译并且行为如您所观察到的:

自动转换:当您指定A(值)的返回类型时,编译器期望创建并返回A对象。如果您提供 A&&(通过 std::move(rhs)),编译器会将其解释为从 rhs 移动构造 A 的指令,而不是复制它。编译器认为 rhs 是右值,并使用移动构造函数来构造返回值。

返回类型推导和临时实现:如果返回类型是按值,编译器将在返回右值时隐式执行移动。在这种情况下,A func(A& rhs) 指定 A 的返回类型,因此编译器将 std::move(rhs) 视为右值,使用移动构造函数创建临时 A。

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.