右值引用和左值引用作为参数之间的差异

syd*_*dgm 5 c++ overloading reference rvalue lvalue

阅读文章后:http : //www.cprogramming.com/c++11/rvalue-references-and-move-semantics-in-c++11.html

我无法弄清楚在编写将左值或右值引用作为参数的函数时,例如:

void printReference (const string& str)
{
    cout << str;
}

void printReference (string&& str)
{
    cout << str;
}
Run Code Online (Sandbox Code Playgroud)

为什么第一个printReference函数可以接受任何参数whether it be an lvalue or an rvalue,和regardless of whether the lvalue or rvalue is mutable or not。但是,在第二个printReference函数中,just allow to pass mutable rvalue.

可能是我的理解是错误的,任何人都可以帮助我解决这个问题。

Tar*_*ama 5

第一个选项可以采用左值,因为它是左值引用。它可以使用rvalues,因为它已被标记const并且允许rvalues绑定到constlvalue引用。

第二个版本只允许使用非const右值,因为您不能隐式地删除const引用对象,并且右值引用不允许左值绑定到它们。

语义上的区别在于,前一个函数在说“我只是要阅读您在此处传递的内容,而我不想复制它”,而后者在说“我保留从该对象中剔除胆量的权利。和他们一起画我的客厅”。

  • 哈哈哈哈,有趣的比喻!它帮助我在生活中牢记 (2认同)

Vla*_*cow 5

只有常量左值引用可以绑定到临时对象。

所以这个函数

void printReference (const string& str)
{
    cout << str;
}
Run Code Online (Sandbox Code Playgroud)

可以为以下对象调用:

const std::string s1( "constant lvalue" );
printReference( s1 );

std::string s2( "non-constant lvalue" );
printReference( s2 );

printReference( "A temporary object of type std::string" );

printReference( static_cast<const std::string>( "A temporary object of type std::string" ) );
Run Code Online (Sandbox Code Playgroud)

至于这个功能

void printReference (string&& str)
{
    cout << str;
}
Run Code Online (Sandbox Code Playgroud)

在上述对象中,您只能为非常量右值调用它。

printReference( "A temporary object of type std::string" );
Run Code Online (Sandbox Code Playgroud)

你可能不会这样称呼它

printReference( static_cast<const std::string>( "A temporary object of type std::string" ) );
Run Code Online (Sandbox Code Playgroud)

由于存在 const 限定符。

如果您将按以下方式重载该功能

void printReference (const string&& str)
                     ^^^^^
{
    cout << str;
}
Run Code Online (Sandbox Code Playgroud)

然后这个电话

printReference( static_cast<const std::string>( "A temporary object of type std::string" ) );
                 
Run Code Online (Sandbox Code Playgroud)

将有效。