Skip to content

fmt::format_to + FMT_STRING does not support user types #1567

@refnum

Description

@refnum

fmt::format_to can use FMT_STRING to validate the format string, while formatting to a fmt::memory_buffer to avoid allocating a std::string.

This works successfully for built-in types but fails to compile for user-defined types with a 'call to deleted constructor of' error (Xcode 11.3.1).

struct MyPoint
{
    int32_t x;
    int32_t y;
};

template <>
struct fmt::formatter<MyPoint>
{
    constexpr auto parse(format_parse_context& ctx)
    {
        return ctx.end();
    }

    template <typename FormatContext>
    auto format(const MyPoint& point, FormatContext& ctx)
    {
        return format_to(ctx.out(), "{}-{}", point.x, point.y);
    }

};



static void TestFunc()
{
    
    int32_t x = 111;
    int32_t y = 222;
    MyPoint thePoint{333, 444};


    // OK
    fmt::memory_buffer out1;
    fmt::format_to(out1, FMT_STRING("Hello {} and {}"), x, y);


    // Fails
    std::vector<char> out2;
    fmt::format_to(std::back_inserter(out2), FMT_STRING("Hello {}"), thePoint);


    // Fails
    fmt::memory_buffer out3;
    fmt::format_to(out3, FMT_STRING("Hello {}"), thePoint);

/*
 /tmp/fmt_2020_02_18/include/fmt/format.h:2582:12: error: call to deleted constructor of 'conditional_t<has_formatter<mapped_type, context>::value, formatter<mapped_type, char_type>, internal::fallback_formatter<MyPoint &, char_type> >' (aka 'fmt::v6::internal::fallback_formatter<MyPoint &, char, void>')
   auto f = conditional_t<has_formatter<mapped_type, context>::value,
            ^
 /tmp/fmt_2020_02_18/include/fmt/format.h:2595:23: note: in instantiation of function template specialization 'fmt::v6::internal::parse_format_specs<MyPoint &, fmt::v6::basic_format_parse_context<char, fmt::v6::internal::error_handler> >' requested here
         parse_funcs_{&parse_format_specs<Args, parse_context_type>...} {}
                       ^
 /tmp/fmt_2020_02_18/include/fmt/format.h:2642:54: note: in instantiation of member function 'fmt::v6::internal::format_string_checker<char, fmt::v6::internal::error_handler, MyPoint &>::format_string_checker' requested here
   format_string_checker<Char, ErrorHandler, Args...> checker(s, eh);
                                                      ^
 /tmp/fmt_2020_02_18/include/fmt/format.h:2651:17: note: in instantiation of function template specialization 'fmt::v6::internal::do_check_format_string<char, fmt::v6::internal::error_handler, MyPoint &>' requested here
       internal::do_check_format_string<typename S::char_type,
                 ^
 /tmp/fmt_2020_02_18/include/fmt/format.h:3286:13: note: in instantiation of function template specialization 'fmt::v6::internal::check_format_string<MyPoint &, FMT_STRING, 0>' requested here
   internal::check_format_string<Args...>(format_str);
             ^
 /tmp/test.cpp100:2: note: in instantiation of function template specialization 'fmt::v6::format_to<FMT_STRING, MyPoint &, 500, char>' requested here
         format_to(out3, FMT_STRING("Hello {}"), thePoint);
         ^
 /tmp/fmt_2020_02_18/include/fmt/core.h:709:3: note: 'fallback_formatter' has been explicitly marked deleted here
   fallback_formatter() = delete;
   ^
 1 error generated.
*/
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions