is there a way in modern C++ to "extend" a function? Maybe this pseudo code can explain what I want:
extendable void foo()
{
doSomething();
}
extend foo()
{
moo();
}
when compiled the function foo()
should do this:
foo()
{
doSomething();
moo();
}
I thought I could do this by storing every function that I want to have in foo()
in a std::vector of function pointers and foo()
will loop through the vector and run all functions.
However, I need to do this while compiling, thus I can't run vector.push_back()
.
I tried to do this with help of #define directives but I didn't find a solution.
Thanks in advance for any answer.
EDIT: My actual problem
I want to implement some kind of Entity-Component-System with a list for every component. Every entity has an ID that points to the list element in the component-list. Because I don't want to repeat the steps for creating a new type of component I wanted to make a #define-directive to make this automatically for every new component I'll create.
The main problem is to add to every component-vector one element if a new entity is created. This is the code I wanted to work:
#define addComponent(name) \
struct name; \
private: \
std::vector<name> name ## vector; \
public: \
extend addEntity() \
{ \
struct name a; \
name ## vector.push_back(a); \
} \
void set ## name(const int & ID, name newName) \
{ \
name ## vector[ID] = newName; \
} \
name get ## name(const int & ID) \
{ \
return name ## vector[ID]; \
}
class Component
{
public:
Component();
~Component();
extendable void addEntity(int * ID);
addComponent(position)
struct position
{
float x, y, z;
}
};
You don't explain enough what you have in mind and why (even after your edit). For member functions, indeed read more about vtables (a common way to implement dynamic dispatch).
Notice however that functions can be values (thanks to lambda expressions and std::function notably).
You might then declare for example a double ended queue
todoque
of functions using std::dequeue (it could be astatic
variable or a field of someclass
, etc...)and extend it, perhaps using a lambda,
and initialize it with
then code
I hope you got the idea.
BTW, in the example above the lambda are perhaps unneeded, you might just code
todoque.push_back(moo)
.BTW I recommend reading SICP (not about C++, but about a functional programming language called Scheme), it is an excellent (and freely downloadable) introduction to programming.
No, or even better, make it a
std::vector<std::function<void(void)>>
and use lambda expressions.Why not? It might happen in a constructor of some static data.
Maybe your overall goal (which you don't explain) might be also achieved by run-time metaprogramming techniques involving JIT compiling and generation of code at runtime. You could use libraries like libgccjit or LLVM; you could also emit C++ code in some temporary file, compile it as a plugin, and dlopen that plugin. See also this.
Regarding your edited Entity-Component-System goal, did you consider writing some specialized C++ code generator (or preprocessor) that appropriate rules of your build automation system (e.g.
make
orninja
, etc...) would trigger wisely at build time? The Qt moc could be inspirational. Consider also using some general purpose preprocessor likem4
or gpp.No.
What you describe is not possible. Having the compiler generate a function that will call the function that
foo()
invoked before being extended is not supported by any mechanism.Virtual methods do not do the trick, since all they provide is Polymorphism (many forms in Greek).