0

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

AathakA
  • 117
  • 7
  • Is `STRUCT(example, (arg1, arg2, arg3))` or `STRUCT(example, arg1, arg2, arg3)` acceptable? – Jarod42 Jan 10 '22 at 13:16
  • Sadly not, because I would need to replicate a function call, such as example(arg1, arg2, arg3); – AathakA Jan 10 '22 at 13:19
  • `STRUCT(example)(arg1, arg2, arg3)` perhaps? It would still involve higher-level indirection tricks, including creation of a class that has an `operator()(T*...)` to forward the extra arguments. – MSalters Jan 10 '22 at 13:47
  • @MSalters Well that would be the best solution so far – AathakA Jan 10 '22 at 13:56
  • The updated question really makes me wonder about the quality of the underlying design. Storing function pointers in `void*` ? IIRC, it's implementation-defined whether that is even possible. The 21st century solution would be `std::function` – MSalters Jan 10 '22 at 14:54
  • @MSalters The functions I' m talking about are CUDA kernels and cannot be stored in the way you mentioned, I also feel like this is getting unhelpfully out of topic – AathakA Jan 10 '22 at 15:01

2 Answers2

2

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

Ted Lyngmo
  • 93,841
  • 5
  • 60
  • 108
  • There is no tool with macros to distinguish the "example" from the parameters? I was hoping with some workaround to be able to accomplish it – AathakA Jan 10 '22 at 13:41
  • 1
    @AathakA: `STRUCT(example(arg1, arg2, arg3))` is a macro **with one argument**. You can expand that one argument one time, or two, but each time you expand the macro argument the whole macro argument `example(arg1, arg2, arg3)` will be expanded. – MSalters Jan 10 '22 at 13:45
  • 1
    @AathakA Not that I know of but leave the question open for a few hours and perhaps someone with magic macro skills comes along and is able to solve that. – Ted Lyngmo Jan 10 '22 at 13:45
  • @MSalters I updated the question, in the hope there are solutions – AathakA Jan 10 '22 at 14:38
0

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.

MSalters
  • 173,980
  • 10
  • 155
  • 350