В проекте, над которым я работал, есть макрос, который записывает выражение. Мне было поручено добавить возможность передавать в него несколько значений и получать каждый отпечаток отдельно.
Мне удалось сравнительно легко работать с 1-5 аргументами. Он даже отлично работает, будучи переданным в функцию.
Проблема, с которой я столкнулся сейчас, состоит в том, что списки инициализатора больше не работают. В проекте использовались переменные аргументы для инициализации массива внутри него, например func(std::vector<int>{0, 1, 0, 1})
. Так как я реализовал много arg, это больше не работает из-за запятых.
Я знаю, что могу сделать func((std::vector<int>{0, 1, 0, 1}))
, и это будет прекрасно работать, но я знаю, что это не понравится в качестве обходного решения. Есть ли способ заставить их работать без дополнительных скобок или добавить дополнительные скобки при необходимости?
Вот некоторые соответствующие фрагменты:
// Intermediate macro "chooser"
#define func_x(x, A, B, C, D, E, Func, ...) Func
// Macro to be called and used by user
// First param must be blank to allow for 0 argument function
#define func(...) func_x(, ##__VA_ARGS__, \
func_5(__VA_ARGS__), func_4(__VA_ARGS__), func_3(__VA_ARGS__), \
func_2(__VA_ARGS__), func_1(__VA_ARGS__), func_0())
// Macros for 1 through 5 args, calls the func_VA macro.
#define func_1(A1) func_VA(A1)
#define func_2(A1, A2) func_1(A1), func_VA(A2)
#define func_3(A1, A2, A3) func_2(A1, A2), func_VA(A3)
#define func_4(A1, A2, A3, A4) func_3(A1, A2, A3), func_VA(A4)
#define func_5(A1, A2, A3, A4, A5) func_4(A1, A2, A3, A4), func_VA(A5)
// Prints expression and type
// We use a variadic macro to support commas inside expressions (e.g.
// initializer lists):
#define func_VA(...) \
func_macro::DebugOutput(__FILE__, __LINE__, __func__, #__VA_ARGS__) \
.print(func_macro::type_name<decltype(__VA_ARGS__)>(), (__VA_ARGS__))
func(std::vector<int>{0, 1, 0, 1});
// Errors
func((std::vector<int>{0, 1, 0, 1}));
// Works, but also prints the () when logging so not ideal. Better than nothing though.
У меня естьпытался установить скобки вокруг определенных частей моих макросов, чтобы попытаться исправить это, но безрезультатно. Как #define func_1(A1) func_VA((A1))
или аналогичный.
РЕДАКТИРОВАТЬ: я добился некоторого прогресса
Объявление func_1
как #define func_1(...) func_VA(__VA_ARGS__)
теперь работает, если я вызываю func_1(std::vector<int>{0, 1, 0, 1});
, как вы можете предположить.
Я создал макрос «обертка», который возвращает (__VA_ARGS__)
, и это позволяет макросу корректно работать со списком init, хотя строковая версия имеет дополнительные скобки. Хотя я не могу заставить это работать таким образом, чтобы вам (как пользователю) не приходилось вызывать оболочку для ваших массивов (что сложнее, чем ставить скобки на место).