2

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

Haianos
  • 21
  • 2
  • Why would you need something like this? – David G Jul 03 '13 at 01:21
  • Only one comment: One of the most important features that comes with C++11 variadic templates are variadic template functions. That is, a type-safe sustitute of the unsafe, error-prone, and very limmited variadic functions (And variadic macros with it) that C++ inherited from C. Why you are trying to merge both? – Manu343726 Jul 14 '13 at 21:21
  • Self-aware datatype, i.e. using the name of the variables (from the user-code) to be visible later on, instead of using sequences of numbers...Application examples, named tuples, for instance (see get).I don't want the user has to provide structs/additional code for something that is already there – Haianos Jul 30 '13 at 09:39
  • Please clarify me, I don't understand what are you trying to do. Your goal is to store the names of the variables used as argumments in a certain function call? – Manu343726 Jul 30 '13 at 10:19
  • Yes. But more than store, build up a struct having as member names the same names used in the argument of a certain function call, such that mystruct.name_var (or similar) will be available. Also a solution based on string could be fine (somehow), but still I have to parse the function signature to get these names... – Haianos Jul 30 '13 at 10:55

2 Answers2

1

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;
}
v.oddou
  • 6,476
  • 3
  • 32
  • 63
0

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

Manu343726
  • 13,969
  • 4
  • 40
  • 75
  • Anyway I agree with your answer and I was tackling the problem in the wrong way - but I was wondering if was possible get more from the precompiler. By the way, I already noticed that I get only the last variable name defined in the code... – Haianos Jul 30 '13 at 09:43
  • With great patience, you can do almost anything in the C preprocessor. e.g check out Boost.Preprocessor. – Clay Bridges Jun 02 '14 at 14:55