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);}\
精彩评论