1

I was just looking through lvalue(Value categories) from cppreference.com and came across member access operator that specifies as :

In Built in Access operator of type E1.E2 :

3) if E2 is a static member function, the result is an lvalue designating that static member function. Essentially, E1 is evaluated and discarded in this case;

and For non-static member function :

4) if E2 is a non-static member function including a destructor, the result is a special kind of prvalue designating that non-static member function of E1 that can only be used as the left-hand operand of a member function call operator, and for no other purpose;

I have no idea of what this means, especially how Point no 3) is used as lvalue and for what purpose. I know this is some detailed stuff which anyone rarely uses.. But out of curiosity, any help with any kind of example will be appreciated ::

463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185
Tilak_Chad
  • 111
  • 3

3 Answers3

2

This is the simplified example from 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
}

Now, the part you quote states that a.sf is a lvalue, while a.f is not. What does that mean? It implies that you can take the address of a.sf:

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

while the same is not true for 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'
463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185
1

You can for example take the address of a static member function and store it in a normal function pointer (so not a member function pointer):

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
}

This makes also sense, since you can call f (only) without providing an object of type X while you can only call g when you provide such an object. Since you want to be able to call a function pointer by *p(0), you cannot allow &g to be assigned to p while there is no problem with &f.

You can think of a public static member function roughly as a free friend function (not exactly but its closer to that than to a non-static member function) accessible through the struct/class.

n314159
  • 4,990
  • 1
  • 5
  • 20
1

Consider:

struct X{
    static void foo(){}

    void bar(){}
};

X makeX(){
  std::cout<<"make X called"<<std::endl;
  return X();
}

int main(){
  makeX().foo();
  makeX().bar();
}

In the call to makeX().foo(), foo is a static member function, so makeX() corresponds to E1 in case 3): it is thus evaluated and discarded, so makeX() is called, but then the temporary X object is discarded and foo is called just as if you had typed X::foo().

In the call to makeX().bar(), bar is a non-static member function, so makeX() is evaluated, and the temporary X object is used as the this parameter for the call to bar.

Anthony Williams
  • 66,628
  • 14
  • 133
  • 155