以下程序使用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
}
这当然很方便,但我不明白它是如何工作的。
答案 0 :(得分:9)
是的,这是标准的。 [func.wrap.func.inv]指定operator()(ArgTypes&&... args)
个std::function
来电
INVOKE
(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)
定义为INVOKE
(f, t1, t2, ..., tN)
隐式转换为R
。
您给出的第一个也是唯一一个参数是指向Foo
- 对象的指针。因此,对method
的调用会产生调用(void)((*t1).*f)()
,当使用您的指定值写入时,该调用等同于((*(&myFoo)).&Foo::bar)()
,相当于myFoo.bar()
。