什么& (&符号)在成员函数签名的末尾是什么意思?

时间:2017-10-29 16:53:45

标签: c++ c++11

我不记得是哪一次谈话,但最近我看了一些来自CppCon 2017的演讲,并且有人提到了某种旁注,那是唯一真正的重载方式{{ 1}}将采用以下方式:

operator=

他明确强调尾随class test { public: test& operator=(const test&) &; }; ,但没有说明它的作用。

那它做了什么?

2 个答案:

答案 0 :(得分:8)

Ref-qualifiers不是C ++ 17的特性(查看问题的标签),但它是C ++ 11中引入的一个特性。

struct Foo
{
  void bar() const &  { std::cout << "const lvalue Foo\n"; }
  void bar()       &  { std::cout << "lvalue Foo\n"; }
  void bar() const && { std::cout << "const rvalue Foo\n"; }
  void bar()       && { std::cout << "rvalue Foo\n"; }
};

const Foo&& getFoo() { return std::move(Foo()); }

int main()
{
  const Foo c_foo;
  Foo foo;

  c_foo.bar();    // const lvalue Foo
  foo.bar();      // lvalue Foo
  getFoo().bar(); // const rvalue Foo
  Foo().bar();    // rvalue Foo
}

参见例如以下博客文章简要介绍:

可能从CppCon谈话中解释你的回忆引用的意图,

  

“......唯一真正的重载方式operator= ......”

我们访问[over.match.funcs]/1, /4 & /5 [强调我的]:

  

/ 1 [over.match.funcs]的子条款描述了候选函数集和提交给重载的参数列表   在使用重载决策的每个上下文中的分辨率。 ...

     

/ 4 对于非静态成员函数,隐式对象参数的类型为

     
      
  • (4.1) - 对于声明没有引用限定符或 X引用限定符&的左值引用” >

  •   
  • (4.2) - 使用X ref-qualifier

  • 声明的函数的“对cv &&的rvalue引用”   
     

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

     

/ 5 ...对于非静态成员函数声明没有引用限定符,应用其他规则:      

      
  • (5.1) - 即使隐式对象参数不是const限定的,也可以将rvalue绑定到参数   在所有其他方面,参数可以转换为类型   隐式对象参数。 [注意:这样的参数是这样的事实   rvalue不会影响隐式转换的排名   序列。 - 尾注]
  •   

从上面的/ 5开始,以下重载(省略了显式&引用限定符)

struct test
{
    test& operator=(const test&) { return *this }
}

允许将值分配给r值,例如

int main()
{
    test t1;
    t1 = test(); // assign to l-value
    test() = t1; // assign to r-value
}

但是,如果我们使用& ref-qualifier明确声明重载,[over.match.funcs]/5.1不适用,并且只要我们不提供使用&& ref-声明的重载限定符,r值赋值将不被允许。

struct test
{
    test& operator=(const test&) & { return *this; }
};

int main()
{
    test t1;
    t1 = test(); // assign to l-value
    test() = t1; // error: passing 'test' as 'this' argument discards qualifiers 
}

在声明自定义赋值运算符重载是“唯一真正的重载方式&”operator=引用限定符提出任何意见>,但是我敢于推测,那么我猜这个声明背后的意图是将排除在 -r-value赋值之外,如上所述。

答案 1 :(得分:2)

根据http://en.cppreference.com/w/cpp/language/member_functions 您的成员函数声明后面的lvalue ref-qualifierthis

换句话说,它要求&&为l值(隐式对象参数具有对cv-qualified X 的类型lvalue引用)。 还有this,需要#include <iostream> struct S { void f() & { std::cout << "lvalue\n"; } void f() &&{ std::cout << "rvalue\n"; } }; int main(){ S s; s.f(); // prints "lvalue" std::move(s).f(); // prints "rvalue" S().f(); // prints "rvalue" } 作为r值。

从文档中复制( const-,volatile-和ref-qualified成员函数):

children