c++constexprfmtgcc11gcc10

workaround for dynamic formatting specs with fmt


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


Solution

  • 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.