开发者

Macro errors with member function

I'm having fun with macros (not)

#include <iostream>

using namespace std;

#define DEF_ATTRIBUTE(type, name) type name;\
    typedef void (*type_name_t)(CLASS_NAME*);\
    type_name_t ptr_type_name;\
    void type_name(){( ptr_type_name = &CLASS_NAME::type_name);}\

class Test
{
    public:
        #define CLASS_NAME Test
        DEF_ATTRIBUTE(int, i_Test);

        void Print()
        {
            cout << "Test::Print()" << endl;
        }
};

int main()
{
    Test t;
    t.Print();
}

Which expands to :

class Test
{
    public:

        int i_Test; typedef void (*type_name_t)(Test*); type_name_t ptr_type_name; void type_name(){( ptr_type_name = &Test::type_name);};

        void Print()
        {
            c开发者_JAVA技巧out << "Test::Print()" << endl;
        }
};

And yields the compiler error :

main.cpp: In member function void Test::type_name():

main.cpp:16: error: cannot convert void (Test::)() to void ()(Test*) in assignment

As far as I can understand, the function pointers are equivalent. What am I doing wrong?


The pointer types are not equivalent: A type_name_t is a function pointer (a pointer to a free function), whereas &Test::type_name is a pointer to member function. This is what the compiler is telling you.

The reason you can't convert a pointer to member function to a simple function pointer is that a (non-static) member function has a hidden this parameter. You can't call a member function through a plain function pointer since there would be no way to pass the this parameter. You're trying to account for this by giving your type_name_t a CLASS_NAME* parameter -- conceptually the right thing to do, but C++ doesn't work that way.

Instead, what you need to do is to delare type_name_t as a pointer to member function:

typedef void (CLASS_NAME::*type_name_t)();

(Untested. I hope the syntax is right; I don't use pointers to member functions on a daily basis.)


The function pointers aren't equivalent.

void (*type_name_t)(Test*)

is not the same as

&Test::type_name

Your function pointer is of type: a pointer to a function that takes one argument, a Test pointer, and returns no value.

What you want is a pointer-to-member-function, specifically, a pointer to a member function that takes no arguments and returns no value:

void (Test::*type_name_t) (); // note the empty parameter list!


The types are different.

&Test::type_name is a pointer to member function of class Test whereas type_name_t cannot hold the address of any member function of class Test. Its just a pointer to a free function (not to a member function).

Try this:

#define CLASS_NAME Test
#define DEF_ATTRIBUTE(type, name) type name;\
    typedef void (CLASS_NAME::*type_name_t)();\
    type_name_t ptr_type_name;\
    void type_name(){( ptr_type_name = &CLASS_NAME::type_name);}\
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜