c++c++20fmt

fmt `fmt::v10::basic_format_string` with C++20


I have the following code:

#include <fmt/core.h>

template <typename ...T>
void func( const fmt::format_string<T...>& str, T&& ...args )
{
    auto _ = fmt::format( str, args... );
}

int main()
{
    func( "foo {}", 3 );
}

(See here for live example)

This compiles and works the way I expect it to if I use --std=c++17; however, it does not compile if I use --std=c++20. Specifically, I get this error:

consteval fmt::v10::basic_format_string<Char, Args>::basic_format_string(const S&) ... (with S= and a bunch of akas) ... in constant expression

What is the difference in C++20 that causes this to break? How can I fix this code to comply with C++20?

I am using fmt v10.0.0.


Solution

  • You have a fmt::format_string<int>. When you call fmt::format( str, args... ), args... expands to a single lvalue int, so the first argument needs to be a fmt::format_string<int&>.
    (The error is it tries to call format_string::operator string_view, which is not marked constexpr. The error only happens in C++20 because it is only a consteval constructor in C++20)

    You need to forward the arguments so they have the right value category:

    auto _ = fmt::format( str, std::forward<T>(args)... );