Reputation: 21
I am struggling with challenging, but yet simple problem. Let say that I have a target function as follow
void target_fnc(int arg1, double arg2)
{ /* do something here */ }
and what I would like to "extract" is the variable names (i.e. 'arg1', 'arg2'). It is trivial to fetch this information for a variable with some preprocess, for instance
#define PRINTER(name) printer(#name)
void printer(const std::string& name) {cout << name << endl;}
and I can also use variadic macros in case of multiple variables
#define PRINTER2(names...) printer(#names)
printer(arg1,arg2)
but I don't have any clue of how to "extract" from a target function..for instance, using variadic templates tecniques as follow
template <typename ...A>
void extract(void (*)(A...))
{ printer(A...); }
It won't work: I will obtain 'A...' and not the unpacked variables, of course... Any tips?
Thanks! Note: I'm using C++11, gcc 4.8.1
Upvotes: 2
Views: 1749
Reputation: 6775
There is an order by which compilation steps are executed, and the one you would want is not the one that we have.
The preprocessor is executed first; then when finished, the C++ build starts. Templated things being build-time, does not grant them miraculous power to feed the preprocessor, it's the other way around.
Yes it would be nice to be able to reflect symbol names and stringify them, and stuff, but it has to be done from the preprocessor interface or a pre-build step using generators.
There are massive proposals for reflection:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0255r0.pdf
or
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1240r0.pdf
in C++ but I don't know when it's going to be a thing.
Otherwise you could attempt things like
http://pfultz2.com/blog/2012/07/31/reflection-in-under-100-lines/
REFLECTABLE
(
(const char *) name,
(int) age
)
int main()
{
Person p("Tom", 82);
print_fields(p);
return 0;
}
Upvotes: 1
Reputation: 14174
CPP is only a copy-paste text system. Its not dessigned to do that kind of magic. In fact, it only does stupid "When you see X , put Y" operations.
In your case, if you try to iterate over the variadic pack:
inline void print(const std::string& name) { std::cout << name << std::endl; }
#define PRINT(name) print(#name)
//Base case:
void extract() {}
//Recursive case:
template<typename HEAD , typename... TAIL>
void extract(const HEAD& head , const TAIL& tail...)
{
PRINT(head);
extract(tail...);
}
You only get:
head
head
head
head
...
The answer is: Avoid the use of the CPP for stupid things, only use it for #ifdef #endif
header guards and portable compilation.
Note that GET_GREATHER(x,y) ((x) > (y) ? (x) : (y))
like macros are not included. C++ has since the beggining of its history a powerfull tool to avoid macros: inline functions
Upvotes: 0