More precisely, I have a class:
struct S
{
template <class... T>
S(std::string instance_name, T*... ptrs);
}
That needs to be constructed in a way like:
STRUCT(example(arg1, arg2, arg3));
Where STRUCT is the macro that expands to:
S example(std::string("example"), arg1, arg2, arg3);
I have been trying with #define X(a) #a but can't figure out how to make it all work.
Thanks
EDIT:
I have a map filled with pairs of <std::string, void*> where functions pointers are stored. Those functions stored there have a counterpart function with the signature: example(Args args), where both functions have same arguments.
So I have entries in the map such as ("example", &example_counterpart) and I want the user to be able to call example_counterpart(...) with something like: OTHER(example(Args args));
The solution you gave is quite close, but the function is called (in the constructor of S) with MACRO(example, arg1, arg2), which is not exactly what I need.
I m open to other suggestions to achieve this, the use of the class is just an idea I had but its not important, the things I cant change is the fact I have those counterpart functions stored in a map and I need to call them with some sort of flag to differentiate it from the normal function call.
I hope my intent it's clear, even tho the reasons might not
CodePudding user response:
Suggestion:
#define STRUCT(inst,...) S inst(std::string(#inst),__VA_ARGS__)
It would then be used slightly different from what you want:
STRUCT(example, arg1, arg2, arg3);
... but it expands to exactly what you want:
S example(std::string("example"), arg1, arg2, arg3);
CodePudding user response:
STRUCT(example(arg1, arg2, arg3)) will expand macro #define STRUCT(a) ... with a=example(arg1, arg2, arg3). Hence, #a will be "example(arg1, arg2, arg3)".
You're going to need to a type for example, and that type will need to capture #a. I.e. Helper<S, #a> with Helper<S, const char* name> a template class derived from S. Slight catch: you can't pass that string literal directly, you'll need to capture it in a helper variable.
In Helper<S, name> you'll need to (constexpr) parse name, and the initializer list of Helper<S>::Helper(T*...args) will need to pass both that parsed name and args... down to S::S.
