C++11 不带ref限定符的非静态成员函数

C++11 不带ref限定符的非静态成员函数,c++11,methods,overloading,non-static,C++11,Methods,Overloading,Non Static,这是一项后续行动 关于 在 常量、volatile和ref限定成员函数 非静态成员函数可以声明为没有ref限定符,。。。 在重载解析期间,非静态cv限定了 X类按如下方式处理: 无ref限定符:隐式对象参数的类型为左值 引用cv限定X,另外允许绑定右值 隐含对象参数 为了进一步探索这一点,我尝试了上面链接中提供的源代码,如下所示: #include <utility> #include <iostream> using std::move; using std::cout

这是一项后续行动

关于

常量、volatile和ref限定成员函数

非静态成员函数可以声明为没有ref限定符,。。。 在重载解析期间,非静态cv限定了 X类按如下方式处理:

无ref限定符:隐式对象参数的类型为左值 引用cv限定X,另外允许绑定右值 隐含对象参数

为了进一步探索这一点,我尝试了上面链接中提供的源代码,如下所示:

#include <utility>
#include <iostream>
using std::move;
using std::cout;
using std::endl;

struct S {
    void f() {cout << "no ref-qualifier: the implicit object parameter has type lvalue reference to cv-qualified S and is additionally allowed to bind rvalue implied object argument\n"; }

    //if only the below method signature were to be enabled,
    //the invocations using rvalue implicit object would fail
    //to compile with the error [-fpermissive]
    //void f() & {cout << "lvalue\n"; }

    //if only the below method signature were to be enabled,
    //the invocation using lvalue implicit object would fail
    //to complile with the error [-fpermissive]
    //void f() && {cout << "rvalue\n"; }
};

int main (void){

    S s;
    s.f();       // prints "lvalue"
    move(s).f(); // prints "rvalue"
    S().f();          // prints "rvalue"

    return 0;
}
#包括
#包括
使用std::move;
使用std::cout;
使用std::endl;
结构{

void f(){coutConst-and-ref限定成员函数的功能与非Const/ref成员函数没有区别。这些标记主要用于防止程序员误用东西

不,这个对象是常量,因为你不应该改变它,所以 不允许对其调用变异函数

  • 编译器对程序员大喊大叫
如果您有一个函数
void g()const
,那么它不会突然编译成不同的指令,因为您从中删除了
const
——这只是意味着编译器停止检查您是否在主体中对
这一
进行了变异

大多数情况下,它变得有点复杂,因为通过维护各种不变量,这些关键字有时也允许程序员(或编译器)使用做一般情况下不允许做的事情。例如,如果我知道你给了我一个右值,那么我可以偷它的内脏,而不需要复制它们

无论如何,为了举例说明,我把你的三个例子都讲了一遍

在第一种情况下,
void f()
编译为:

S::f():
  push rbp
  mov rbp, rsp
  sub rsp, 16
  mov QWORD PTR [rbp-8], rdi
  mov esi, OFFSET FLAT:.LC0
  mov edi, OFFSET FLAT:_ZSt4cout
  call std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)
  nop
  leave
  ret
使用ref限定符:

main:
  sub rsp, 8
  mov esi, OFFSET FLAT:.LC0
  mov edi, OFFSET FLAT:_ZSt4cout
  call std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)
  mov esi, OFFSET FLAT:.LC0
  mov edi, OFFSET FLAT:_ZSt4cout
  call std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)
  mov esi, OFFSET FLAT:.LC0
  mov edi, OFFSET FLAT:_ZSt4cout
  call std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)
  xor eax, eax
  add rsp, 8
  ret
_GLOBAL__sub_I_main:
  sub rsp, 8
  mov edi, OFFSET FLAT:_ZStL8__ioinit
  call std::ios_base::Init::Init() [complete object constructor]
  mov edx, OFFSET FLAT:__dso_handle
  mov esi, OFFSET FLAT:_ZStL8__ioinit
  mov edi, OFFSET FLAT:_ZNSt8ios_base4InitD1Ev
  add rsp, 8
  jmp __cxa_atexit
main:
        sub     rsp, 8
        mov     esi, OFFSET FLAT:.LC0
        mov     edi, OFFSET FLAT:_ZSt4cout
        call    std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)
        mov     esi, OFFSET FLAT:.LC1
        mov     edi, OFFSET FLAT:_ZSt4cout
        call    std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)
        mov     esi, OFFSET FLAT:.LC1
        mov     edi, OFFSET FLAT:_ZSt4cout
        call    std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)
        xor     eax, eax
        add     rsp, 8
        ret
_GLOBAL__sub_I_main:
        sub     rsp, 8
        mov     edi, OFFSET FLAT:_ZStL8__ioinit
        call    std::ios_base::Init::Init() [complete object constructor]
        mov     edx, OFFSET FLAT:__dso_handle
        mov     esi, OFFSET FLAT:_ZStL8__ioinit
        mov     edi, OFFSET FLAT:_ZNSt8ios_base4InitD1Ev
        add     rsp, 8
        jmp     __cxa_atexit
main:
副区长,8
mov esi,偏移平坦:.LC0
移动edi,偏移平面:_ZSt4cout
调用std::basic_ostream&std::operator
main:
        sub     rsp, 8
        mov     esi, OFFSET FLAT:.LC0
        mov     edi, OFFSET FLAT:_ZSt4cout
        call    std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)
        mov     esi, OFFSET FLAT:.LC1
        mov     edi, OFFSET FLAT:_ZSt4cout
        call    std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)
        mov     esi, OFFSET FLAT:.LC1
        mov     edi, OFFSET FLAT:_ZSt4cout
        call    std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)
        xor     eax, eax
        add     rsp, 8
        ret
_GLOBAL__sub_I_main:
        sub     rsp, 8
        mov     edi, OFFSET FLAT:_ZStL8__ioinit
        call    std::ios_base::Init::Init() [complete object constructor]
        mov     edx, OFFSET FLAT:__dso_handle
        mov     esi, OFFSET FLAT:_ZStL8__ioinit
        mov     edi, OFFSET FLAT:_ZNSt8ios_base4InitD1Ev
        add     rsp, 8
        jmp     __cxa_atexit