Home > Enterprise >  Add the instance name to the constructor arguments as an std::string with Macros
Add the instance name to the constructor arguments as an std::string with Macros

Time:01-11

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);

Demo

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.

  •  Tags:  
  • Related