右值引用和左值引用作为参数的区别

difference between rvalue reference and lvalue reference as argument

看完post: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;
}

为什么 first printReference 函数可以接受任何参数,无论它是左值还是右值,并且 不管 左值是否或右值是否可变。 但是,在 second printReference 函数中,只允许传递可变右值。

可能是我的理解有误,谁能帮我解答下

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

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

语义上的区别是前一个函数说的是"I am just going to read what you pass in here and I'd rather not copy it",而后者说的是"I reserve the right to rip the guts out of this object and paint my living room with them"。

只能将常量左值引用绑定到临时对象。

所以这个函数

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

可能会为以下对象调用:

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" ) );

至于这个功能

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

在上面提到的对象中,您只能为非常量右值调用它。

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

你可能不会这样称呼它

printReference( static_cast<const std::string>( "A temporary object of type std::string" ) );

由于存在 const 限定符。

如果您将按以下方式重载函数

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

然后这个调用

printReference( static_cast<const std::string>( "A temporary object of type std::string" ) );
                 

将有效。