3372. vformat_to should not try to deduce Out twice

Section: 28.5.5 [format.functions] Status: C++20 Submitter: Tim Song Opened: 2020-01-16 Last modified: 2021-02-25

Priority: 0

View all other issues in [format.functions].

View all issues with C++20 status.

Discussion:

vformat_to currently deduces Out from its first and last arguments. This requires its last argument's type to be a specialization of basic_format_args, which notably prevents the use of format-arg-store arguments directly. This is unnecessary: we should only deduce from the first argument.

[2020-02-01 Status set to Tentatively Ready after six positive votes on the reflector.]

Proposed resolution:

This wording is relative to N4842.

  1. Edit 28.5.1 [format.syn], header <format> synopsis, as indicated:

    namespace std {
    
      […]
    
      template<class Out>
        Out vformat_to(Out out, string_view fmt, format_args_t<type_identity_t<Out>, char> args);
      template<class Out>
        Out vformat_to(Out out, wstring_view fmt, format_args_t<type_identity_t<Out>, wchar_t> args);
      template<class Out>
        Out vformat_to(Out out, const locale& loc, string_view fmt,
                       format_args_t<type_identity_t<Out>, char> args);
      template<class Out>
        Out vformat_to(Out out, const locale& loc, wstring_view fmt,
                       format_args_t<type_identity_t<Out>, wchar_t> args);
    
      […]
    }
    
  2. Edit 28.5.5 [format.functions] p8 through p10 as indicated:

    template<class Out, class... Args>
      Out format_to(Out out, string_view fmt, const Args&... args);
    template<class Out, class... Args>
      Out format_to(Out out, wstring_view fmt, const Args&... args);
    

    -8- Effects: Equivalent to:

    using context = basic_format_context<Out, decltype(fmt)::value_type>;
    return vformat_to(out, fmt, {make_format_args<context>(args...)});
    
    template<class Out, class... Args>
      Out format_to(Out out, const locale& loc, string_view fmt, const Args&... args);
    template<class Out, class... Args>
      Out format_to(Out out, const locale& loc, wstring_view fmt, const Args&... args);
    

    -9- Effects: Equivalent to:

    using context = basic_format_context<Out, decltype(fmt)::value_type>;
    return vformat_to(out, loc, fmt, {make_format_args<context>(args...)});
    
      template<class Out>
        Out vformat_to(Out out, string_view fmt, format_args_t<type_identity_t<Out>, char> args);
      template<class Out>
        Out vformat_to(Out out, wstring_view fmt, format_args_t<type_identity_t<Out>, wchar_t> args);
      template<class Out>
        Out vformat_to(Out out, const locale& loc, string_view fmt,
                       format_args_t<type_identity_t<Out>, char> args);
      template<class Out>
        Out vformat_to(Out out, const locale& loc, wstring_view fmt,
                       format_args_t<type_identity_t<Out>, wchar_t> args);
    

    -10- Let charT be decltype(fmt)::value_type.

    […]