Search code examples
c++stringstlformatc++20

Passing variadic template parameter to another function with a variadic template parameter


I'm currently writing a logger for my engine and I've been stuck with a problem I could not solve. std::format takes in a constant string and a list of arguments after.

My Log functions is as follows:

template <typename... Args>
void Log(const char* message, Args&&... args)

Now in somewhere in the function scope, I try to format the string by:

std::string formattedMsg = std::format(message, args);

And I try to mess with it:

Scope<Colour::Logger> myLogger = CreateScope<Colour::Logger>("MyLogger");
myLogger->Log("Hey! I have a variable named \"a\" and it is equal to {0}", a);
myLogger->Info("Hey! I have a variable named \"a\" and it is equal to {0}", a);
myLogger->Log("Hey! I have a variable named \"a\" and it is equal to {0}", a);
myLogger->Warn("Hey! I have a variable named \"a\" and it is equal to {0}", a);
myLogger->Error("Hey! I have a variable named \"a\" and it is equal to {0}", a);
myLogger->Fatal("Hey! I have a variable named \"a\" and it is equal to {0}", a);
myLogger->Info("Hey! I have a variable named \"a\" and it is equal to {0}", a);

Scope is unique_ptr, CreateScope is make_unique. Info, Fatal, Trace etc. functions just set the level to correct one and call Log().

But that gives me the error:

std::_Basic_format_string::_Basic_format_string': call to immediate function is not a constant expression

I tried doing stuff like taking in a _Fmt_String, std::string, const char*, I tried expanding the arguments, forwarding them but none of them work. How can I format this message parameter using the args parameter using std::format?


Solution

  • This might get you started :

    #include <iostream>
    #include <format>
    
    template <typename... args_t>
    void Log(std::string_view fmt, args_t&&... args)
    {
        std::string formatted_message = std::vformat(fmt, std::make_format_args(args...));
        std::cout << formatted_message << "\n";
    }
    
    int main()
    {
        Log("Hello {0}{1}", "World", "!");
        return 0;
    }