Мне нужен макрос для передачи __FILE__ и __LINE__ функции с аргументами по умолчанию. Это открыло банку червей, поскольку аргументы по умолчанию с макросами либо невозможны, либо очень запутаны, и мне нужно поддерживать как GCC, так и MSVC, если это возможно:
class Class
{
#ifdef _DEBUG
int Function(int a, int b = 10, int c = 20) { return a + b + c; }
#else
int DebugFunction(const char* filename, int lineNo, int a, int b = 10, int c = 20)
{
printf("%s (%i) a:%i b:%i c:%i\n", filename, lineNo, a, b, c);
return a + b + c;
}
//Not possible
#define Function( DebugFunction(__FILE__, __LINE__
#endif
}
Я пытался \экранировать ( безрезультатно. Кодовая база огромна, поэтому исправление отсутствующих аргументов по умолчанию или создание нескольких макросов не является популярным вариантом.
Любые решения?
Ответ 1 · рейтинг 6 · Kerrek SB
Вы можете сделать вариативный макрос:
#define Function(...) DebugFunction(__FILE__, __LINE__, __VA_ARGS__)
Поскольку вы не можете "перегружать" макросы, это может быть вашим лучшим выбором.
Ответ 2 · рейтинг 3 · templatetypedef
Одним из вариантов было бы переписать вашу основную функцию Function следующим образом:
int Function(const char* filename, int lineNo, int a, int b = 10, int c = 20)
{
#ifdef _DEBUG
printf("%s (%i) a:%i b:%i c:%i\n", filename, lineNo, a, b, c);
#endif
return a + b + c;
}
Таким образом, все вызовы направляются к одной и той же функции, но поведение этой функции зависит от того, установлен ли у вас флаг _DEBUG. Это позволяет обойти проблему аргументов по умолчанию, поскольку у вас есть обычный вызов функции с условным включением кода, а не макрос, которому может потребоваться много аргументов.
Надеюсь это поможет!
Ответ 4 · рейтинг 1 · tbert
Не большой парень С++, но пробовали ли вы что-то вроде (в псевдокоде)
#ifdef debug
#define Function(args) _Function(__file__, __line__, (args))
int _Function(char *file, int line, args) { /* code */ }
#else
#define Function(args) _Function(args)
int _Function(args) { /* code */ }
#endif
Конечно, сама функция должна иметь возможность принимать несколько версий аргументов; Я действительно не вижу другого способа сделать это.