C++ 有没有一种方法可以在没有。*或->;*的情况下调用成员函数操作人员

C++ 有没有一种方法可以在没有。*或->;*的情况下调用成员函数操作人员,c++,boost,cdecl,C++,Boost,Cdecl,下面通过指向成员函数的指针调用D::foo函数的方法将生成错误:必须使用*或->*调用指向“f(…)”中成员函数的指针。 .. 当然,这不是我们调用成员函数指针的方式 正确的调用方式是(d.*f)(5)或(p->*f)(5) 我的问题是,‘有没有一种方法可以在左侧没有类对象的情况下调用类的成员函数?我想知道是否可以将类对象(this)作为常规参数传递 在我看来,在一天结束时(在汇编/二进制级别),一个类的所有成员函数都是正常函数,应该在n+1个参数上操作,其中(+1代表this) 如果我们在下面

下面通过指向成员函数的指针调用
D::foo
函数的方法将生成错误:必须使用
*
->*
调用指向“f(…)”中成员函数的指针。
.. 当然,这不是我们调用成员函数指针的方式

正确的调用方式是
(d.*f)(5)
(p->*f)(5)

我的问题是,‘有没有一种方法可以在左侧没有类对象的情况下调用类的成员函数?我想知道是否可以将类对象(
this
)作为常规参数传递

在我看来,在一天结束时(在汇编/二进制级别),一个类的所有成员函数都是正常函数,应该在n+1个参数上操作,其中(+1代表
this

如果我们在下面讨论
D::foo
函数,那么在程序集/二进制级别,它应该在两个参数上操作:

  • 类对象本身(指向名为this
  • 的D类对象的指针)
  • int
  • 那么,有没有一种方法(或hack)来调用
    D::foo
    ,将class对象作为函数参数传递给它,而不是使用
    。或->或。*或->*
    类对象上的运算符

    示例代码:

    #include <iostream>
    using namespace std;
    
    class D {
        public:
            void foo ( int a ) {
                cout << "D" << endl;
            }
    
            int data;
    };
    
    
    //typedef void  __cdecl ( D::*  Func)(int);
    typedef void ( D::*  Func)(int);
    
    int main ( void ) 
    {
        D d;
    
        Func f = &D::foo;
        f(&d, 5);
    
        return 1;
     }
    
    编辑:
    “请注意,我不是在寻找这个程序的一个有效版本,我知道如何使它工作”

    我不太确定您的要求。通过指向成员的指针调用函数没有“人为限制”;您只需使用正确的语法:

    (d.*f)(5);  // for objects or references
    (p->*f)(5); // for pointers
    
    bind
    没有任何“魔力”;在它的实现中,它确实做到了这一点

    最后,它是一个接受两个参数的函数

    不,它是一个成员函数,接受一个参数,并在对象上调用。虽然在概念上类似于接受两个参数的函数,但有一个很大的区别:成员函数可以是虚拟的,涉及运行时调度机制

    但必须有一种方法来避免这种人为的限制 由c强加++


    你所说的“人为限制”是什么意思?这只是语言定义的语法。怎么了?
    bind()
    的“魔力”将在内部使用
    ->*
    操作符来调用函数。

    您真的想在不使用
    ->
    的情况下调用成员函数吗?真的吗,真的吗?好吧,好吧

    邪恶。h:

    #ifdef __cplusplus
    extern "C" {
    #endif
    
    struct MyStruct
    {
    #ifdef __cplusplus
        MyStruct();
    
        void method(int);
    #endif
    };
    
    #ifdef __cplusplus
    }
    #endif
    
    Evil.cc:

    #include <iostream>
    
    #include "evil.h"
    
    MyStruct::MyStruct() { std::cout << "This is MyStruct's constructor" << std::endl; }
    
    void MyStruct::method(int i) { std::cout << "You passed " << i << std::endl; }
    
    这恰好适用于我在Linux上的gcc和g++组合,但不用说它依赖于平台ABI,并且在调用下划线大写字母形式的函数时违反了C89标准。它几乎肯定不会与虚拟函数一起工作,我也不想尝试。这可能也是我写过的最邪恶的东西。但还是


    编辑:引用OP:

    在我看来,在一天结束时(在汇编/二进制级别),一个类的所有成员函数都是正常函数,应该在n+1个参数上操作,其中(+1代表
    this

    虽然自CFront以来的每个编译器都是这样做的,但这只是一个实现细节。C++标准是在Prime< Stime>不中指定成员函数应该如何实现,而只是它们应该如何执行。

    因为这是一个实现细节,不同的平台以不同的方式实现。这不仅仅是名称上的混乱。例如,Linux上使用的调用约定指定将
    this
    作为第一个参数传递;其他实现(Borland,IIRC?)将
    这个
    作为最后一个参数

    因此,如果您想将成员函数视为具有额外
    this
    的普通函数,那么您必须将自己限制为特定的ABI。这篇文章提供了一个你如何做到这一点的例子(或者更确切地说,一个你为什么真的不应该这么做的例子!)

    那么,有没有一种方法(或黑客)调用D::foo,并将类对象作为函数参数传递给它,而不是使用。类对象上的or->or.*或->*运算符

    一个特定于平台的恶心的肮脏黑客

    有没有一种方法可以在左侧没有类对象的情况下调用类的成员函数

    那么,有没有一种方法(或hack)可以调用
    D::foo
    ,将class对象作为函数参数传递给它,而不是在class对象上使用
    ->
    *
    运算符

    简而言之,不可以。如果不在调用的左侧指定对象,就不能调用非
    静态
    类成员函数。如果未指定类(对于静态函数)或对象(对于非静态函数),则编译器无法知道要调用哪个函数。它位于当前范围之外,因为它位于类或对象内部。有几种方法可以“破解”代码,这样您就可以将其编写成示例中的
    main()
    。其他一些答案给出了这类黑客的例子

    ------------使用静态函数-----------------

    类内的函数可以在类外调用,而无需指定类对象。方法是为函数指针创建一个签名与类函数匹配的
    typedef
    ,然后创建这样一个指针并为其分配类函数的地址。然后可以调用该函数,而无需在左侧指定类或对象

    函数必须是
    静态的。ISO C++不允许使用绑定成员函数的地址来形成指向该函数的指针,即不能从类对象创建指向非代码>静态< /COD>成员函数的指针。您可能会找到一些非ISO标准兼容的编译器,但我没有任何指导

    参数
    this
    为非
    static
    cla
    #include <iostream>
    
    #include "evil.h"
    
    MyStruct::MyStruct() { std::cout << "This is MyStruct's constructor" << std::endl; }
    
    void MyStruct::method(int i) { std::cout << "You passed " << i << std::endl; }
    
    #include "evil.h"
    
    int main()
    {
        struct MyStruct my_struct;
        _ZN8MyStructC1Ev(&my_struct); /* MyStruct::MyStruct() */
    
        _ZN8MyStruct6methodEi(&my_struct, 3); /* MyStruct::method(int) */
    
        return 0;
    }
    
    fastdelegate::FastDelegate0<> functionObject;
    SomeClass someInstance;
    
    //fill in object and function information in function object
    functionObject.bind(&someInstance,&SomeClass::someFunction);
    
    //call function via object.  Equivalent to: someInstance->someFunction();
    functionObject();
    
    #include <iostream>
    using namespace std;
    
    class D {
        public:
            void foo ( int a ) {
                cout << "D" << endl;
            }
    
            int data;
    };
    
    
    typedef void ( D::*  Func)(int);
    
    int main ( void ) 
    {
        D d;
        D *pThis = &d;
    
        Func f = &D::foo;
    
        /* invoke function pointer via a "class" pointer */
        (pThis->*f)(5);
    
        /* invoke function pointer via a "class" object */
        (d.*f)(5);
    
        return 1;
    }
    
    ~/prj/stackoverflow
    # g++ funcptr.cpp 
    
    ~/prj/stackoverflow
    # ./a.out 
    D
    D
    
    void foo(int a) {}
    
    static void foo(D *pthis, int a) {}
    
    int main(void)
    {
        D d;
        int a = 0;
        D::foo(&d, a); /* call foo, w/o using . or -> and providing your own this pointer */
        return 0;
    }
    
    #include <iostream>
    using namespace std;
    
    class D {
        public:
            void foo ( int a ) {
                cout << "D" << endl;
            }
    
            int data;
    };
    
    template<class Object, class Param, class Function>
    class FunctionPointerHelper                                           
    {                                                    
    private:                                             
        Function m_function;                             
    public:                                              
        FunctionPointerHelper(Function function) :                        
            m_function(function)                         
        {                                                
        }                                                
        void operator=(Function function)                
        {                                                
            m_function = function;                       
        }                                                
        void operator()(Object& object, Param param) const      
        {                                                
            (object.*m_function)(param);                 
        }                                                
    };
    
    #define TYPEDEF_NICE_FUNCTION(RESULT, CLASS, NEW_TYPENAME, PARAM) \
    typedef RESULT ( CLASS::* NEW_TYPENAME_INTERMEDIATE)(PARAM) ; \
    typedef FunctionPointerHelper<CLASS, PARAM, NEW_TYPENAME_INTERMEDIATE> NEW_TYPENAME;
    
    TYPEDEF_NICE_FUNCTION(void, D, Func, int)
    
    int main ( void ) 
    {
        D d;
    
        Func f = &D::foo;
        f(d, 5);
    
        return 1;
     }
    
    #include <iostream>
    using namespace std;
    
    class D {
        public:
            void foo ( int a ) {
                cout << "D" << endl;
            }
    
        static void foo(D& d, int a)
        {
            d.foo(a);
        }
    
            int data;
    };
    
    void foo(D& d, int a)
    {
        d.foo(a);
    }
    
    int main ( void ) 
    {
        D d;
    
        D::foo(d, 5);
        foo(d, 5);
    
        return 0;
    }
    
    int main ( void ) 
    {
        D d;
    
        auto f = std::bind( &D::foo, _1, _2 );
        f(&d, 5);
     }
    
    #include <iostream>
    
    template<typename T, typename Ret, typename... Args>
    Ret call_member(Ret (T::*mem)(Args...), T* obj, Args... args)
    {
        return (obj->*mem)(args...);
    }
    
    struct S {
        void foo(int i) { std::cout << "Foo: " << i << '\n'; }
    };
    
    int main()
    {
        S s;
    
        call_member(&S::foo, &s, 5);
        return 0;
    }