AS there is no build-in reflection in C++, in resulting code all ids will be gone. But you can emulate it by using stringize operator #, if you don't mind to use some wrappers. assert() macro in some implementations makes use of it.
#include <iostream>
void order(int arg1, int arg2, const char* str)
{
std::cout << str << arg1*arg2 << std::endl;
}
#define REFLECT_INVOKE(func, ...) (func)(__VA_ARGS__, #func "(" #__VA_ARGS__ ") = ")
int main()
{
int x = 6;
int y = 11;
REFLECT_INVOKE(order,x,y);
}
Output:
order(x,y) = 66
Operator # literally wraps following token in quotes before placing result into processed source before compilation, so statement REFLECT_INVOKE(order,x,y);
is processed into (order)(x,y,"order" "(" "x,y" ") = ");
We can make it a bit more universal, using new features (there is probably simple and obvious way to do this):
int order(int arg1, int arg2)
{
return arg1*arg2;
}
template<class F, class ...Args>
auto debug_call( F func, const char* str, Args... args) ->
decltype(std::forward<F>(func)(std::forward<Args>(args)...))
{
if constexpr ( std::is_same<decltype(std::forward<F>(func)(std::forward<Args>(args)...)),void>::value) {
std::cout << str;
func(args...);
} else {
auto res = func(args...);
std::cout << str << "= " << res;
return res;
}
}
#define REFLECT_INVOKE(func, ...) (debug_call)(func, #func "(" #__VA_ARGS__ ") ", __VA_ARGS__)
int main()
{
int x = 6;
int y = 11;
REFLECT_INVOKE(order,x,y);
}
This is barely usable outside of debugging purposes.