将对象指针作为成员函数的第一个参数传递:它是标准的吗?

时间:2014-11-01 19:36:34

标签: c++ c++11

以下程序使用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
}

这当然很方便,但我不明白它是如何工作的。

1 个答案:

答案 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的成员函数的指针时,t1T类型的对象或者参考   类型为T的对象或对从中派生的类型的对象的引用   T;

  •   
  • ((*t1).*f)(t2, ..., tN)f是指向类T的成员函数的指针时,t1不是其中一种类型   上一项;

  •   
  • [...]
  •   

请注意,调用中的结尾R用于转换为Rfunction的返回类型):

  

INVOKE (f, t1, t2, ..., tN, R)定义为 INVOKE (f, t1, t2, ..., tN)隐式转换为R

您给出的第一个也是唯一一个参数是指向Foo - 对象的指针。因此,对method的调用会产生调用(void)((*t1).*f)(),当使用您的指定值写入时,该调用等同于((*(&myFoo)).&Foo::bar)(),相当于myFoo.bar()