为什么函数参数(Myclass)可以有L和R值,但相同的返回类型(Myclass)只能返回R值?

Why a function parameter(Myclass) can have L and R values but same return type (Myclass) can only returns R value?

提问人:UPinar 提问时间:3/11/2023 最后编辑:Vlad from MoscowUPinar 更新时间:3/11/2023 访问量:60

问:

我很难理解这个概念。 我可以发送 L 值和 R 值作为参数

Myclass foo(Myclass)

但不能从该函数返回 L 和 R 值。只有 R 值出来。

我想知道为什么会这样?

class Myclass {};

Myclass fooReturnsL(Myclass b)
{
    Myclass a;
    return a;
}

Myclass fooReturnsR(Myclass b)
{
    return Myclass{};
}

int main()
{
    Myclass var_Myclass;

    Myclass& lref = fooReturnsL(var_Myclass); // sythax error
    Myclass& lref = fooReturnsL(Myclass{}); // sythax error

    Myclass&& rref = fooReturnsR(var_Myclass); // no error  
    Myclass&& rref = fooReturnsR(Myclass{}); // no error
}

有没有随时可以返回 L 值?Myclass fooReturnsL(Myclass b)

C++ 函数 逐个引用 声明

评论

0赞 Eljay 3/11/2023
要成为左值,它需要有一个名称。返回值没有名称。
1赞 SebastianWilke 3/11/2023
fooReturnsL(var_Myclass)并且是纯右值 (en.cppreference.com/w/cpp/language/value_category)。因此,它们不能绑定到左值引用,因为这将允许更改临时引用。fooReturnsL(Myclass{})

答:

1赞 Vlad from Moscow 3/11/2023 #1

此功能

Myclass fooReturnsL(Myclass b)
{
    Myclass a;
    return a;
}

返回具有自动存储持续时间的对象,该对象在退出函数后将不处于活动状态。

因此,您不能返回不存在的对象的引用。

例如,您可以声明该函数

Myclass &  fooReturnsL(Myclass &b)
{
    //... some other code
    return b;
}

并称它为

Myclass var_Myclass;

Myclass& lref = fooReturnsL(var_Myclass); 

如果尝试从函数返回对具有自动存储持续时间的本地对象的引用,则程序行为将未定义。

考虑以下演示程序(前提是它将被编译)

#include <iostream>

class Myclass 
{
public:
    ~Myclass() 
    { 
        std::cout << "Myclass::~Myclass() called\n" ;
    }
};

Myclass & fooReturnsL()
{
    Myclass a;
    return a;
}


int main()
{
    Myclass &t = fooReturnsL();

    std::cout << "Press any key to continue...";
}

程序输出为

Myclass::~Myclass() called
Press any key to continue... 

如您所见,函数中声明的对象已销毁。所以引用是一个悬空的引用。

评论

0赞 UPinar 3/11/2023
当我在函数中创建一个对象时,有一个自动存储持续时间,并且在函数执行后它不会处于活动状态,但我也可以与 main() 中的 L 值引用绑定,例如Myclass obj;Myclass& foo(Myclass a)return objobjMyclass& lref = foo(var_Myclass)
1赞 Vlad from Moscow 3/11/2023
@UPinar 此类代码具有未定义的行为。
0赞 UPinar 3/11/2023
还有 1 个问题,当发送 var_Myclass 或 Myclass{} 作为参数复制 ctor 时调用对吗?if 函数如下所示Myclass& foo(Myclass)
0赞 Vlad from Moscow 3/11/2023
@UPinar 对于用作参数表达式的临时对象,可以省略复制构造函数。它被称为复制构造函数省略。
0赞 UPinar 3/11/2023
哦,很酷,所以直接在 foo() 函数堆栈中创建的 Myclass 对象,就像一个临时对象