workaround for dynamic formatting specs with fmt

582 Views Asked by At

Is there a way to use fmt with a spec that is computed at runtime.

Noticed that with gcc 10 this code worked fine but not with modern gcc.

#include <fmt/format.h>

const char* get_spec(bool test)
{ // image this is implemented in some other .cpp file
    return test ? "->{}" : "{}<-";
}

int main() {
    const char* non_constexpr = get_spec(true);
    fmt::print(non_constexpr,1);
}

https://godbolt.org/z/oh9n3cEnT

2

There are 2 best solutions below

0
On BEST ANSWER

You need to use fmt::runtime():

#include <fmt/format.h>

const char* get_spec(bool test)
{ // image this is implemented in some other .cpp file
    return test ? "->{}" : "{}<-";
}

int main() {
    const char* non_constexpr = get_spec(true);
    fmt::print(fmt::runtime(non_constexpr),1);
}

Like always, gcc has bad error descriptions. The problem is that the normal constructor for format patterns is consteval in C++20, so you cannot pass a runtime format to it.

For that purpose, just use fmt::runtime() around your runtime format pattern.

In case of C++20's std::format problem, you need to use std::vformat to resolve the problem as mentioned in cpp ref.

0
On

You can use fmt::vprint (std::vprint_unicode in C++23) for runtime format string

const char* non_constexpr = get_spec(true);
int arg = 1;
fmt::vprint(non_constexpr, fmt::make_format_args(arg));