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

时间:2015-11-20 14:52:19

标签: c++ reference overloading lvalue rvalue

阅读帖子后: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;
}

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

可能是我的理解是错的,任何人都可以帮我解决它。

2 个答案:

答案 0 :(得分:5)

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

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

语义上的区别在于前者的功能是说“我只是要阅读你在这里传递的内容,我宁愿不复制它”,而后者则说“我保留了撕掉内心的权利”这个物体和他们一起画我的起居室“。

答案 1 :(得分:2)

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

所以这个功能

void printReference (const string& str)
{
    cout << str;
}
可以为以下对象调用

const std::string s1( "constnat 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;
}

然后在上述对象中,您可以仅将其称为非常数rvalue

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

有效。