2
#define LOG_INFO(str, ...)                                              \
  logger.NewLogStateMent(__FILE__, __LINE__,                            \
                         fver::base::log::Logger::LogLevel::kInfo, str, \
                         ##__VA_ARGS__)
void NewLogStateMent(const char* filename, const int len, LogLevel lev, ...) {
  std::cout << fmt::format("{} {} {} {} {}", filename, lne, lev, ...);
}
// use case
int main () {
  LOG_INFO("hello, world %d", 1);
}

Now i want to this LOG_INFO(str, ...) to a fmt::format();

But the Gcc give me a lot of errors gcc version: 12.2.0

c++ version: c++17

How can i finish it?

Please help me!

vitaut
  • 49,672
  • 25
  • 199
  • 336
fan
  • 21
  • 1
  • 1
    You probably want `NewLogStateMent` to be a variadic function template, not a C-style variadic function. It's unclear though how and by whom you expect `%d` specifier to be interpreted. It has no special meaning to `format` – Igor Tandetnik Aug 26 '22 at 14:32
  • yep, i just want to make the args to fmt::format ? so can you give me some helps or suggestions? – fan Aug 26 '22 at 14:37
  • In your example, what's the expected output you hope it'll produce? – Igor Tandetnik Aug 26 '22 at 14:38
  • we know fmt::format can help us automatric format strings such as fmt::format("hello {} world", 1); -> "hello 1 world" so i want to LOG_INFO("hello {} world", 1), -> "filename fileline info hello 1 world", like this. – fan Aug 26 '22 at 14:42

2 Answers2

2

Something along these lines:

#define LOG_INFO(str, ...) \
  NewLogStateMent(__FILE__, __LINE__, \
                         "info", str, \
                         ##__VA_ARGS__)

template <typename... Args>
void NewLogStateMent(const char* filename, const int line, const char* level,
                     const std::string& format_str, Args&&... args) {
  std::cout << fmt::format("{} {} {} ", filename, line, level)
            << fmt::format(fmt::runtime(format_str), std::forward<Args>(args)...);
}

// use case
int main () {
  LOG_INFO("hello {} world", 1);
}

Demo

Igor Tandetnik
  • 50,461
  • 4
  • 56
  • 85
  • Ok, Thank you! but there some warngins for gcc; ``` warning: __VA_ARGS__ can only appear in the expansion of a C++11 variadic macro ``` such like this, can you help me to fix it? – fan Aug 27 '22 at 09:22
  • The example shown doesn't appear to elicit that warning. To the extent there is a problem, it likely lies in the code not shown. – Igor Tandetnik Aug 27 '22 at 13:31
  • ok i forget enable -std=c++20 thank you! – fan Aug 28 '22 at 01:59
1

Here's how to do it with compile-time checks (https://godbolt.org/z/EE1zxcdrK):

#include <fmt/core.h>

#define LOG_INFO(str, ...)                                              \
  NewLogStatement(__FILE__, __LINE__, "info", str, ##__VA_ARGS__)

template <typename... T>
void NewLogStatement(const char* filename, int line, const char* level,
                     fmt::format_string<T...> fmt, T&&... args) {
  fmt::print("{} {} {} ", filename, line, level);
  fmt::print(fmt, std::forward<T>(args)...);
}

int main () {
  LOG_INFO("hello {} world", 1);
}
vitaut
  • 49,672
  • 25
  • 199
  • 336