以下程序同时使用 gcc 和 clang 进行编译,但这实际上是标准的 C++11 还是两个编译器都选择支持它以方便?
struct Foo {
int i;
void bar() { std::cout << i << std::endl; }
};
int main() {
std::function<void(Foo*)> method = &Foo::bar;
Foo myFoo{4};
method(&myFoo); // prints 4
}
这当然很方便,但我不明白它是如何/为什么工作的。
是的,这是标准的。[func.wrap.func.inv] 指定std::function
调用的operator()(ArgTypes&&... args)
调用
(f, std::forward<ArgTypes>(args)..., R)
(20.8.2(,其中f
是*this
的目标对象 (20.8.1(。
(其中R
是指定的返回类型。
[func.require] 定义INVOKE
:
定义
INVOKE
(f, t1, t2, ..., tN)
如下所示:
(t1.*f)(t2, ..., tN)
当f
是指向类T
的成员函数的指针,而t1
是类型T
的对象或对 类型T
的对象或对派生自T
;
((*t1).*f)(t2, ..., tN)
当f
是指向类T
的成员函数的指针并且t1
不是 中描述的类型之一 上一项;- [...]
请注意,调用中的尾随R
用于转换为R
(function
的返回类型(:
将
INVOKE
(f, t1, t2, ..., tN, R)
定义为隐式转换为R
INVOKE
(f, t1, t2, ..., tN)
。
您给出的第一个也是唯一一个参数是指向 Foo
-对象的指针。因此,对method
的调用会导致调用(void)((*t1).*f)()
,当用给定的值编写时,它等效
于 ((*(&myFoo)).&Foo::bar)()
,这等效于 myFoo.bar()
。