【问题标题】:Static member function and access operator静态成员函数和访问运算符
【发布时间】:2019-12-12 12:58:09
【问题描述】:

我只是从 cppreference.com 浏览左值(值类别),发现member access operator 指定为:

在 E1.E2 类型的内置访问运算符中:

3) 如果 E2 是静态成员函数,则结果是指定该静态成员函数的左值。本质上,在这种情况下,E1 被评估并丢弃;

对于非静态成员函数:

4) 如果 E2 是包含析构函数的非静态成员函数,则结果是一种特殊类型的纯右值,指定 E1 的非静态成员函数只能用作成员函数的左操作数呼叫接线员,不得用于其他目的;

我不知道这意味着什么,尤其是第 3 点)如何用作左值以及用于什么目的。 我知道这是一些很少有人使用的详细内容。但出于好奇,任何对任何示例的帮助都将不胜感激::

【问题讨论】:

    标签: c++ lvalue static-functions


    【解决方案1】:

    这是来自 cppreference 的简化示例

    #include <iostream>
    struct A
    {
        int f() { return 10; }
        static int sf() { return 4; }
    };
    
    int main()
    {
        A a;
        std::cout << a.f() << a.sf(); // A::sf() also works
    }
    

    现在,您引用的部分指出 a.sf 是左值,而 a.f 不是。这意味着什么?表示可以取a.sf的地址:

    auto fun = &(a.sf); 
    fun();
    

    a.f 则不然:

    auto fun = &(a.f);   // error 
    // ISO C++ forbids taking the address of a bound member function to form a pointer to member function.  Say '&A::f'
    

    【讨论】:

    • 这并不能解释对静态成员函数的调用如何作为 cppreference 中引用的左值工作......
    • @Tilak_Chad 所以你的问题是关于“......是一个左值......”。我想现在我明白了这个问题;)
    • 我想你想通过*fun() 打电话给fun
    • @n314159 afaik 都很好
    【解决方案2】:

    考虑:

    struct X{
        static void foo(){}
    
        void bar(){}
    };
    
    X makeX(){
      std::cout<<"make X called"<<std::endl;
      return X();
    }
    
    int main(){
      makeX().foo();
      makeX().bar();
    }
    

    在对makeX().foo()的调用中,foo是一个static成员函数,所以makeX()对应于E1在情况3):它因此被评估和丢弃,所以makeX()被调用,但随后临时的 X 对象被丢弃,foo 被调用,就像您输入了 X::foo() 一样。

    在对makeX().bar()的调用中,bar是一个非static的成员函数,所以makeX()被求值,临时的X对象被用作调用的this参数bar.

    【讨论】:

      【解决方案3】:

      例如,您可以获取静态成员函数的地址并将其存储在普通函数指针中(因此不是成员函数指针):

      struct X {
          static void f(int);
          void g(int);
      };
      
      int main() {
          X x;
          void (*p)(int);
          p = &x.f; // works
          p = &x.g; // does not work
      }
      

      这也是有道理的,因为您可以(仅)调用f 而无需提供X 类型的对象,而您只能在提供此类对象时调用g。由于您希望能够通过*p(0) 调用函数指针,因此您不能允许将&amp;g 分配给p,而&amp;f 没有问题。

      您可以将公共静态成员函数大致视为可通过结构/类访问的免费友元函数(不完全是,但它比非静态成员函数更接近)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-08-29
        • 1970-01-01
        • 2013-05-03
        • 2016-04-09
        • 1970-01-01
        • 2011-09-30
        相关资源
        最近更新 更多