Нет реального способа избежать макроса для выполнения stringify.
То, что вы можете сделать, это одеть его более объектно-ориентированным способом на c ++, особенно если вы хотите использовать несколько различных методов, которые принимают объект и его имя переменной, и если это функция отладки, которую вы, возможно, захотите отключить в рабочей среде.
Поэтому я предлагаю вам объявить класс шаблона DebugContextWrap и объекты этого типа (или const ref) может быть передано в функцию как один параметр, вместо того, чтобы иметь 2 параметра.
Единственным недостатком является то, что если ваш код функции действительно хочет получить доступ к фактическому значению, то вам придется выполнить косвенное обращение через operator ->
или data()
, как вы делаете для итераторов.
Затем вы можете написать макрос, который генерирует экземпляры DebugContextWrap - что-то вроде:
template class FooType
class DebugContextWrap
{
FooType& fooVal;
const char* debugName;
const char* debug__FILE__val;
const int debug__LINE__val;
public:
DebugContextWrap(FooType& fooVal,
const char* debugName, const char* debug__FILE__val, const int debug__LINE__val)
{ ... }
DebugContextWrap(FooType& fooVal) // implicit when caller doesn't use DEBUG_WRAP
{ ... }
FooType* operator ->()const
{ return &foo; }
FooType& operator *()const
{ return foo; }
FooType& Data()const
{ return foo; }
const char* DebugName()const
{ return debugName; }
};
#define DEBUG_WRAP(foo) \
DebugContextWrap<decltype foo>(foo, #foo, __FILE__, __LINE__)
void do_sth(const DebugContextWrap<FooType>& foo);
do_sth(DEBUG_WRAP(foovar));