Search code examples
c++formatc++20

Custom formatter failed to compile in clang and gcc, but succeeded in MSVC


Following code failed to compile in gcc 14 (link) and clang 17 (link), yet succeeded in MSVC 17.6.2. gcc and clang throw tons of errors that do not make sense to me. Error message is too lengthy to be posted here. Please refer to the links for details. Could someone help me understand what's going on here? The format library is quite new in gcc and clang. Could this be a library implementation bug?

#include <format>
#include <iostream>

enum struct enum_t: unsigned {
    cat,
    dog
};

template <>
struct std::formatter<enum_t>: formatter<unsigned> {
    auto format(enum_t v, format_context& ctx) {
        return formatter<unsigned>::format(unsigned(v), ctx);
    }
};

int main() {
    std::cout << std::format("{}", enum_t::cat) << '\n';
}

Solution

  • As far as the error produced with libstdc++ is concerned:

    According to the BasicFormatter requirements, it must be possible to call format on a const-qualified object of the type of the formatter specialization.

    Your format member function isn't const-qualified, so it can't be used in such a call (and it also hides the format from the base class).

    You need to const-qualify the member function:

    template <>
    struct std::formatter<enum_t>: formatter<unsigned> {
        auto format(enum_t v, format_context& ctx) const {
            return formatter<unsigned>::format(unsigned(v), ctx);
        }
    };
    

    This requirement isn't in C++20, but is in the current C++23 draft via resolution of LWG 3636. I think it is intended to be a defect report, so that it should also apply if you compile with -std=c++20.

    I don't yet know what issue Clang with libc++ has with the code. I'll investigate...