У меня есть макрос assert, который выглядит так:
#define ASSERT(condition, ...) \
(condition) ? (void)0 : MyLogFunction(__LINE__, __VA_ARGS__)
MyLogFunction
тоже шаблон с вариадой:
template<typename... Args>
void MyLogFunction(int line, const Args&... args) {/*code*/}
Все работает хорошо, за исключением случая, когда я не хочу вставлять дополнительную информацию в вызов assert.
Так что это работает хорошо:
ASSERT(false, "test: %s", "formatted");
Но это не так:
ASSERT(false);
Я полагаю, что есть способ справиться с ситуацией, когда переменные аргументы не были переданы в вызов макроса, и есть способ вставить что-то вроде простой строки ""
вместо __VA_ARGS__
Не совсем решение для макросов, но простой обходной путь — предоставить шаблон вспомогательной переменной, который может получить 0 параметров и выполнить проверку условий там:
#define ASSERT(...) \
MyLogHelper(__LINE__, __VA_ARGS__)
template<typename... Args>
void MyLogFunction(int line, const Args&... ) {/*code*/}
template<typename... Args>
void MyLogHelper(int line, bool condition, const Args&... args)
{
if (!condition) MyLogFunction(line,args...);
}
Нет портативного способа сделать это.
Посмотри на http://en.wikipedia.org/wiki/Variadic_macro