我遇到了这段代码:
auto f3 = std::bind(&Foo::print_sum, &foo, 95, _1);
在前面的代码中,我们可以在没有实例的情况下将地址运算符应用于成员函数 对象已创建,怎么可能?
答案 0 :(得分:5)
C ++的类型系统包含一些鲜为人知的类型,它们是成员指针。给定任何类类型C
以及任何对象或函数类型T
,都有一个指向成员的类型T C::*
。可以通过将address-of运算符应用于类成员的限定名称来获取这些类型的值。例如:
struct Foo;
int Foo::* pi; // C = Foo, T = int
void (Foo::* pf)(bool, int); // C = Foo, T = void(bool, int)
struct Foo {
int a;
int b;
void f(bool, int);
void g(bool, int);
};
pi = &Foo::a;
pf = &Foo::f;
成员指针本身只抽象地选择一个类成员,与任何类实例无关。要实际使用指针,您需要一个类实例,以及member-dereference运算符.*
:
Foo x;
int n = x.*pi; // gets x.a
(x.*pf)(true, n); // calls x.f(true, n)
pf = &Foo::g;
(x.*pf)(true, n); // calls x.g(true, n)
(通过指向成员pf
的调用表达式中的括号是必要的,否则表达式a.*b(c)
表示a.*(b(c))
。这有时会让新用户感到困惑。)
不要将指向成员的指针与指向实际对象的指针混淆对象!
int * p = &(x.*pi); // p = &x.a
此处p
指向实际的int
子对象x.a
并且是普通对象指针,而pi
是指向成员的指针,它抽象地选择{{1} 1}} Foo::a
对象的成员。
答案 1 :(得分:0)
使用Foo
成员函数的地址为您提供指向成员函数的指针。此类型完全独立于任何Foo
对象。如果您要实际调用该函数,则需要提供Foo
对象。在这种情况下,this
的{{1}}参数与Foo::print_sum
绑定到&foo
。
答案 2 :(得分:0)
当然,您需要一个名为Foo
的{{1}}类型的实例,因为成员函数foo
绑定到Foo::print_sum
。