我只是浏览cppreference.com的左值(值类别),遇到了member access operator,它指定为:
E1.E2类型的内置Access运算符:
3)如果E2是静态成员函数,则结果是一个表示该静态成员函数的左值。本质上,在这种情况下,将评估E1并将其丢弃;
和非静态成员函数:
4)如果E2是包含析构函数的非静态成员函数,则结果是一种特殊的prvalue,它指定E1的非静态成员函数只能用作成员函数的左操作数呼叫运营商,无其他目的;
我不知道这意味着什么,尤其是3号点如何用作左值以及用于什么目的。 我知道这是一些任何人都很少使用的详细资料。.但是出于好奇,任何示例方面的任何帮助都将受到赞赏::
答案 0 :(得分:2)
这是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'
答案 1 :(得分:1)
例如,您可以获取静态成员函数的地址,并将其存储在普通函数指针中(而不是成员函数指针中):
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)
调用函数指针,因此在&g
没问题的情况下,您不能允许将p
分配给&f
。
您可以将公共静态成员函数粗略地视为可通过struct / class访问的免费朋友函数(不完全是,但它比非静态成员函数更近)。
答案 2 :(得分:1)
考虑:
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()
对应于情况3)的E1
:因此被求值并被丢弃,因此将调用makeX()
,但随后会丢弃临时X
对象,并像您键入foo
一样调用X::foo()
。
在对makeX().bar()
的调用中,bar
是一个非static
成员函数,因此对makeX()
进行求值,并使用了临时X
对象作为this
调用的bar
参数。