成员函数声明的参数列表后的单个&符号是什么意思?

时间:2014-02-18 17:31:25

标签: c++ c++11

从答案here

class wrap {
public:
   operator obj() const & { ... }   //Copy from me.
   operator obj() && { ... }  //Move from me.
private:
   obj data_;
};

我知道&&表示当对象是右值引用时将调用该成员。但单个&符号是什么意思?与没有&符号有什么不同?

3 个答案:

答案 0 :(得分:51)

这意味着当对象是左值引用时将调用该成员。

  

[C++11: 9.3.1/5]:可以使用 ref-qualifier 声明非静态成员函数(8.3.5);见13.3.1。

     

[C++11: 13.3.1/4]:对于非静态成员函数,隐式对象参数的类型为

     
      对于没有使用 ref-qualifier 或使用X ref-qualifier声明的函数,
  • “对 cv &的左值引用”
  •   对于使用X ref-qualifier 声明的函数,
  • “对 cv &&的rvalue引用”   
     

其中X是函数所属的类, cv 是成员函数声明中的 cv-qualification [..]

     

(还有一些我找不到的规则)

如果没有 ref-qualifier ,无论您调用它的表达式的值类别如何,都可以随时调用该函数:

struct foo
{
    void bar() {}
    void bar1() & {}
    void bar2() && {}
};

int main()
{
    foo().bar();  // (always fine)
    foo().bar1(); // doesn't compile because bar1() requires an lvalue
    foo().bar2();

    foo f;
    f.bar();      // (always fine)
    f.bar1();
    f.bar2();     // doesn't compile because bar2() requires an rvalue
}

Live demo (感谢Praetorian)

答案 1 :(得分:26)

  

但单个&符号是什么意思?

该函数只能在左值上调用,而不是在右值上调用。

  

与没有&符号有什么不同?

如果没有ref-qualifier,你可以在左值右值上调用该函数。

使用ref-qualifier,您只能在相应的值类别上调用该函数。

答案 2 :(得分:9)

可以为rvalue和lvalues调用没有ref-qualifier的函数。只能为rvalues调用具有&& ref-qualifier的函数。只能为左值调用具有& ref-qualifier的函数。

class No { void foo(); };
class L { void foo() &; };
class R { void foo() &&; };

No().foo(); // valid
No no; no.foo(); // valid
L().foo(); // invalid
L l; l.foo(); // valid
R().foo(); // valid
R r; r.foo(); // invalid

不幸的是,我只能在5.5 / 6中找到这个规则,它只适用于指向成员的解引用表达式。我知道它也适用。

此外,你不能在ref-qualifier和ref ref-qualifier上重载,参见13.1 / 2 bullet 3.你可以在& vs &&上重载。

(由于我对标准的搜索毫无结果,LRiO的答案现在也提供了所有这些信息。)