Кормление boost::format с вариативными параметрами

Я пытаюсь написать функцию ведения журнала, которая принимает список аргументов с переменным числом аргументов и печатает в безопасном месте.
vprintf кажется очевидным ответом, но я не могу найти безопасный способ обработки, когда строка формата ожидает больше аргументов, чем были предоставлены.

Кроме того, было бы очень хорошо, если бы я мог изменить порядок вывода параметров.
Это второе требование привело меня к boost::format, что, кажется, именно то, что мне нужно, за исключением того, что оно не принимает va_list для ввода.

Я провел обширный поиск, и самое близкое, что я смог найти, было это решение:
boost:: формат с переменными аргументами шаблона

К сожалению, я ограничен определенной версией gcc, которая, похоже, не включает std::initializer_list

В своих поисках я наткнулся на boost::preprocessor, который, кажется, должен быть в состоянии выполнить то, что я хочу, но я борюсь с его реализацией.

Итак, в идеале я ищу что-то, что работает следующим образом:

void loggerFunc(const char* msgFormat, ...){
    boost::format f(msgFormat);

    va_list args;
    va_start(args, msg);

    f & MagicalFunctionCall(args);

    va_end(args);
}

Где этот MagicalFunctionCall(args) преобразует мои аргументы, например:
1, "Test", 3.4, "OtherString"
во что-то вроде:
1 & "Test" & 3.4 & "OtherString"

На самом деле я не обязательно привязан к boost::preprocessor или чему-то еще boost, но было бы идеально сделать это без каких-либо дополнительных сторонних зависимостей (мы уже используем boost в другом месте проекта). Я просто предложил эти библиотеки, потому что они казались наиболее перспективными для выполнения всего вышеперечисленного.

Спасибо!


person DaBernMon    schedule 13.02.2018    source источник


Ответы (1)


Вместо Boost Format вы можете использовать библиотеку fmt, которая поддерживает старые компиляторы:

void loggerFunc(const char *format, fmt::ArgList args) {
  std::string s = fmt::format(format, args);
  // log s
}
FMT_VARIADIC(void, loggerFunc, const char *)

loggerFunc, сгенерированный FMT_VARIADIC, можно использовать с переменным количеством аргументов:

loggerFunc("{} {} {} {}", 1, "Test", 3.4, "OtherString");

Отказ от ответственности: я являюсь автором библиотеки fmt.

person vitaut    schedule 14.02.2018
comment
Спасибо за ответ! Моя команда была настроена придерживаться наших текущих зависимостей, но я определенно постараюсь использовать это в будущих проектах, это выглядит очень полезным! Кроме того, читая ваш документ, я узнал кое-что об обычной команде printf, которая, казалось, дала мне жизнеспособный обходной путь для этой текущей проблемы. - person DaBernMon; 15.02.2018