Reputation: 8528
I have many variables that are named the same as elements in an engineering specification document so the string version of the name is also useful.
I find myself using a macro like this a lot:
#define MACRO(a) a, #a
Typical usage is:
void someFunction(int a, const char *name);
someFunction(MACRO(meaningfully_named_variable));
My question is threefold:
Edit I should have said that the above is a minimal example. The function might have other parameters and the named entity might be a data member or perhaps even a function itself.
Another extension I'm considering for C++ is a class NamedRef
that could receive the contents of the macro.
template <typename T>
struct NamedRef
{
NamedRef(T *t, const char *name) : t(t), name(name) { }
T *t;
const char *name;
};
template <typename T>
NamedRef<T> namedRef(T &t, const char *name)
{
return NamedRef<T>(&t, name);
}
#define WITH_NAME(a) a, #a
// more sophisticated usage example
void otherFunction(double, NamedRef<int>, bool);
otherFunction(0.0, namedRef(object.WITH_NAME(meaningful_member_name)), false);
Upvotes: 9
Views: 3840
Reputation: 311
As Jesse answered,
you can write like this:
void function1(int a, const char* name)
{
cout << "a: " << a << endl;
cout << "name: " << name << endl;
}
void function2(double d, const char* name, const char *str)
{
cout << "d: " << d << endl;
cout << "name: " << name << endl;
cout << "str: " << str << endl;
}
#define MACRO(functionName, a) functionName(a, #a)
#define MACRO2(functionName, a, ...) functionName(a, #a, __VA_ARGS__)
int main()
{
int a = 10;
MACRO(function1, a);
double d = 10.5;
MACRO2(function2, d, "Hello world");
return 0;
}
If you have more arguments to pass, you can use MACRO2 that uses variable arguments. You will have to pass the function name accordingly.
Upvotes: 0
Reputation: 3968
#define someFunction(a) if (1) stringized_someFunction((a), #a ); else (void)0
void stringized_someFunction(int a, const char* name);
The if (1) stuff wraps up the macro so that it won't mess (usually) with loops, branches, if statements, etc.
You would then call your function like so:
int r = 4;
someFunction(r);
You only really add one extra line for each "function declaration." If the C preprocessor allowed multiple steps you could wrap it all up into one, but alas, it doesn't.
I forgot because I hope it's obvious that you'd need to write your function:
void stringized_someFunction(int a, const char* name)
{
// Do stuff here
}
Anyhow it should be a lot easier and prettier to read that way.
Upvotes: 0
Reputation: 28882
You are likely to find that XMACROs are useful for this kind of work.
Upvotes: 0
Reputation: 52365
You could take it a step further:
#define SOMEFUNCTION(a) somefunction(a, #a)
However, this is only useful if you call the same function alot. Otherwise, I don't think there is any better way than your example. Of course, you should change the name of the macro to something more meaningful though, like ARGUMENTS
or something.
Upvotes: 5