对于&限定的函数,我们只能将它用于左值;对于&&限定的函数,只能用于右值;
如下:
Foo &retFoo(); //返回一个引用;retFoo 调用是一个左值 Foo retVal(); //返回一个值;retVal 调用是一个右值 Foo i,j; // i和j是左值 i=j; //正确:i是左值 retFoo()=j; //正确:retFoo() 返回一个左值 retVal()=j; //错误,retVal() 返回一个右值 i=retVal(); //正确,我们可以将一个右值作为赋值操作的右侧运算对象
下面一个例子来说明可以使用引用限定符&来进行重载:
#include<iostream> #include<vector> #include<algorithm> using namespace std; class Foo { public: Foo sorted() &&; Foo sorted() const &; void print(); Foo(vector<int> vec) { data=vec; } Foo()=default; private: vector<int> data; }; Foo Foo::sorted() && { sort(data.begin(),data.end()); return *this; } Foo Foo::sorted() const & { Foo ret(*this); sort(ret.data.begin(),ret.data.end()); return ret; } void Foo::print() { for(auto vec:data) cout<<vec<<endl; } int main() { Foo foo({2,34,32,56,6,45,1}); foo.print(); foo.sorted(); ((foo.sorted()).sorted()).print(); foo.print(); return 0; }
编译器会根据调用sorted的对象的左值/右值属性来确定使用哪个sorted版本:
retVal().sorted(); //retVal()是一个右值,调用Foo::sorted() && retFoo().sorted(); //retFoo() 是一个左值,调用Foo::sorted() const &
当我们定义const成员函数时,可以定义两个版本,唯一的区别是一个版本有const限定而另一个没有。引用限定的函数则不一样。如果我们定义两个或两个以上具有相同名字核相同参数列表的成员函数,就必须对所有的函数都加上引用限定符,或者都不加。
程序执行结果如下:
[root@localhost 未命名文件夹]# ./Foo 2 34 32 56 6 45 1 1 2 6 32 34 45 56 2 34 32 56 6 45 1