传递对象指针作为成员函数的第一个参数:是标准的吗? [英] Passing object pointer as first argument for a member function: is it standard?

查看:124
本文介绍了传递对象指针作为成员函数的第一个参数:是标准的吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面的程序用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的运算符()(ArgTypes&& ... args)
:function
调用


INVOKE :: forward< ArgTypes>(args)...,R)(20.8.2),其中 f 是目标对象1) * this


$ c> R 是指定的返回类型。)



[func.require] c> INVOKE :


定义 INVOKE (f,t1,t2,...,tN)如下:




  • (t1。* f)(t2,...,tN) / code>是指向类 T t1 的成员函数的指针是类型 T 或对 T 类型的
    对象的引用或对类型派生的对象的引用from
    T ;


  • f 是指向类的成员函数的指针时, T t1 不是在
    中描述的先前项目中的一种类型;


  • / code>在调用中用于转换为 R 函数的返回类型) :


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




    您提供的第一个也是唯一的参数是指向 Foo 对象的指针。因此,调用方法会导致调用(void)((* t1)。* f)()在写入您的给定值时,等效于
    ((*(& my my)))。& Foo :: bar)() myFoo.bar()


    The following program compiles with both gcc and clang, but is this actually standard C++11 or do both compilers choose to support it for convenience?

    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
    }
    

    This is certainly convenient, but I don't understand how/why it works.

    解决方案

    Yes, that is standard. [func.wrap.func.inv] specifies that the operator()(ArgTypes&&... args)
    of std::function calls

    INVOKE (f, std::forward<ArgTypes>(args)..., R) (20.8.2), where f is the target object (20.8.1) of *this.

    (Where R is the specified return type.)

    [func.require] defines INVOKE:

    Define INVOKE (f, t1, t2, ..., tN) as follows:

    • (t1.*f)(t2, ..., tN) when f is a pointer to a member function of a class T and t1 is an object of type T or a reference to an object of type T or a reference to an object of a type derived from T;

    • ((*t1).*f)(t2, ..., tN) when f is a pointer to a member function of a class T and t1 is not one of the types described in the previous item;

    • […]

    Note that the trailing R in the call is used for the conversion to R (the return type of the function):

    Define INVOKE (f, t1, t2, ..., tN, R) as INVOKE (f, t1, t2, ..., tN) implicitly converted to R.

    The first and only argument you give is the pointer to the Foo-object. The call to method thus results in the call (void)((*t1).*f)() which is, when written with your given values, equivalent to
    ((*(&myFoo)).&Foo::bar)(), which is equivalent to myFoo.bar().

    这篇关于传递对象指针作为成员函数的第一个参数:是标准的吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆