This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of LEWG status.

### 3810. CTAD for `std::basic_format_args`

Section: 22.14.8.3 [format.args] Status: LEWG Submitter: Jonathan Wakely Opened: 2022-11-03 Last modified: 2022-11-12

Priority: 3

View all other issues in [format.args].

View all issues with LEWG status.

Discussion:

It seems desirable for this should work:

>     auto args_store = std::make_format_args<C>(1,2,3);
>     // …
>     std::basic_format_args args = args_store;

i.e. CTAD should deduce the `Context` argument from the `fmt-store-args<C, int, int, int>` object returned by `make_format_args`.

Another example (from Tomasz Kamiński):

Given:

>     template<typename Context>
>     void foo(basic_format_args<Context> c);

>     foo(make_format_args<SomeContext>(…)); // won't work
>     foo(basic_format_args(make_format_args<SomeContext>(…))); // should work

Since `fmt-store-args` is exposition-only, it's not entirely clear that it must have exactly the form shown in 22.14.8.2 [format.arg.store]. E.g. maybe it can have different template arguments, or could be a nested type defined inside `basic_format_args`. I don't know how much of the exposition-only spec is actually required for conformance. If CTAD is already intended to be required, it's a bit subtle.

If we want the CTAD to work (and I think it's nice if it does) we could make that explicit by adding a deduction guide.

[Kona 2022-11-12; Set priority to 3, status to LEWG]

Proposed resolution:

This wording is relative to N4917.

1. Modify 22.14.8.3 [format.args] as indicated:

   >     namespace std {
   >       template<class Context>
   >       class basic_format_args {
   >         size_t size_;                           // exposition only
   >         const basic_format_arg<Context>* data_; // exposition only

   >       public:
   >         basic_format_args() noexcept;

   >         template<class... Args>
   >           basic_format_args(const format-arg-store<Context, Args...>& store) noexcept;

   >         basic_format_arg<Context> get(size_t i) const noexcept;
   >       };

   >       template<class Context, class... Args>
   >         basic_format_args(format-arg-store<Context, Args...>) -> basic_format_args<Context>;
   >     }