Skip to content

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

Closed
@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

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions