It looks like creating macro that generate exactly "MyClass _val("val", &a.val)"
from nested member will be very hard to implement without compromise. For clarity, let's split problem into 3 simple issues, and try to solve them one by one:
MYCLASS(a.val); // Should generate "MyClass _val("val", &a.val);"
| | |
issue (3) (2) (1)
Issue (1)
:
This part will be handled without any problem by already shown implementation #define MYCLASS(x) MyClass _##x(#x, &x)
.
Issue (2)
:
float
member in the other class might be also a pointer. Then string after ->
should be taken into consideration. May also happen that object that contain float
is member of other object (nested) e.g:
struct Foo1
{
struct Foo2
{
Foo1* foo1;
};
Foo1* foo1;
Foo2 foo2;
};
MYCLASS(Foo1::foo1->foo2.foo1); // "foo1" is expected in (2)
so to get "foo1"
from very nested float
for (2)
use nameof macro implemented by @Dmitry Bravikov
Issue (3)
:
Here trouble comes. There is Foo1::foo1->foo2.foo1
and we would like to convert it to (3)
by adding underscore _
. If Foo1::foo1->foo2.foo1
will be just predicted by _
code will not compile (variable name can not contain .
, ::
, nor ->
). If not allowed characters will be removed (by normal method or constexpr), such sanitized string (string, std::string, char*, std::array<>) will have to be returned.
Problem is that in C++ there is no way to convert any kind of (string, std::string, char*, std::array<>) to variable name. See Convert string to variable name or variable type. Case is not hopeless because you can use use some hard coded string, but then when you will not be able to use MYCLASS() macro twice in the same scope. You can think about implementation that solves this problem, but probably then you will lose transparency during debugging...
Summary:
I would advise creating two arguments macro MYCLASS(name, val);
(already pointed by @liliscent) as probably the most effective solution for your problem