Reputation: 979
I get an error when initializing a typedef-ed pointer to a member function. Is it because it is typedef-ed before classs declaration? If so, how can I forward declare the typedef so it can be used inside of struct Definition which is then used inside of the B class itself.
Header file:
typedef void (B::* p)()
struct Definition {
p code = nullptr;
void execute() {
code();
}
}
class B
{
private:
void semicolon();
p o;
void (B::* pointer)();
std::list<Definition> definitions;
void definePrimitives();
}
Source file:
void B::definePrimitives() {
o= B::semicolon;// error: expression must be a modifiable l-value
pointer =&B::semicolon;//works
}
Upvotes: 1
Views: 1212
Reputation: 979
The code had a couple of problems: 1) it lacked forward declaration of class B as pointed out by IlBeldus. If you remove forward declaration of class B you will be able to reproduce the error. 2) the execute method inside of Definition struct was wrong. It should be:
struct Definition {
Code code = nullptr;
void execute(B b) {
b.o = &B::semicolon;
(b.*(b.c))();
}
};
in my real application I've defined pointer to B to as a member of Definition. One can't just execute member function by
p(); or code();
one needs to specify the object of type B first, like in my example above:
(b.*(b.c))();
3) Thirdly, my code required struct Definition to be declared below B, and struct Definition had to be forward-declared before B. just like this:
header file:
#include <list>
class B;
using Code = void(B::*)(void);
struct Definition;
class B
{
private:
void (B::* pointer)();
std::list<Definition> definitions;
void definePrimitives();
public:
void semicolon();
Code o = nullptr;
Code c = nullptr;
};
struct Definition {
Code code = nullptr;
void execute(B b) {
b.o = &B::semicolon;
(b.*(b.c))();
}
};
and source file:
#include "Header.h"
#include <list>
void B::semicolon()
{
}
void B::definePrimitives() {
o = &B::semicolon;
pointer = &B::semicolon;
}
int main() {
B b;
return 0;
}
4) and.. in the C++ world one my want to use classes instead of structs all the way, and since we are past c++11 already one might want to use the using clause, instead of typedef.
Upvotes: 0
Reputation: 1040
This works:
class B;
typedef void (B::* p)();
struct Definition {
void execute() {
p();
}
};
class B
{
private:
void semicolon();
p o;
void (B::* pointer)();
std::list<Definition> definitions;
void definePrimitives() {
o= &B::semicolon;
pointer =&B::semicolon;
}
};
Basically you have to take the pointer to the function, not the function itself
Upvotes: 1