在查看STL源码过程中,看到有的函数的参数列表中,对参数前面有"&&"这样的修饰符。甚为不解。
在网上查阅了相关的信息,才发现,这是一种新的参数的引用方法,称之为“右值引用”,区别于左值引用的“&”。
参见MSDN-右值引用。这是VisualStudio2010中新增的支持特性
中文版的好像示例更多:右值引用-MSDN中文页面
举例来说,有如下代码:
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s = string("h") + "e" + "ll" + "o";
cout << s << endl;
}
可以看出,string("h")在表达式中是一个右值。
显然,对string类应有重载的加号运算符,左操作数为string对象,右操作数为const char*,且加号运算符一般应作为友元函数实现。
一般的实现方法是,创建一个新的string对象tmp,然后把左右两边的值都复制到tmp中。这也是最一般的STL函数。如下:
template<class _Elem,
class _Traits,
class _Alloc> inline
basic_string<_Elem, _Traits, _Alloc> operator+(
const basic_string<_Elem, _Traits, _Alloc>& _Left,
const _Elem *_Right)
{ // return string + NTCS
basic_string<_Elem, _Traits, _Alloc> _Ans;
_Ans.reserve(_Left.size() + _Traits::length(_Right));
_Ans += _Left;
_Ans += _Right;
return (_Ans);
}
然而,在有右值引用的基础上,我们就可以重载一个函数,专门为右值的左操作数服务。此时,如果左操作数是右值,那么就可以把右操作数直接附加在左操作数的后面。
如下:
template<class _Elem,
class _Traits,
class _Alloc> inline
basic_string<_Elem, _Traits, _Alloc> operator+(
basic_string<_Elem, _Traits, _Alloc>&& _Left,
const _Elem *_Right)
{ // return string + NTCS
return (_STD move(_Left.append(_Right)));
}
在无法判断左右值的情况下,不能直接附加。因为如果左操作数是左值的话,我们不应该对它进行任何修改。