Issue 3810: CTAD for std::basic_format_args (original) (raw)


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

3810. CTAD for std::basic_format_args

Section: 28.5.8.3 [format.args] Status: C++23 Submitter: Jonathan Wakely Opened: 2022-11-03 Last modified: 2023-11-22

Priority: 3

View all other issues in [format.args].

View all issues with C++23 status.

Discussion:

It seems desirable for this should work:

auto args_store = std::make_format_args(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 void foo(basic_format_args c);

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

Since _fmt-store-args_ is exposition-only, it's not entirely clear that it must have exactly the form shown in 28.5.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]

[2023-01-10; LEWG telecon]

Unanimous consensus in favor.

[Issaquah 2023-02-06; LWG]

Unanimous consent (9/0/0) to move to Immediate for C++23.

[2023-02-13 Approved at February 2023 meeting in Issaquah. Status changed: Immediate → WP.]

Proposed resolution:

This wording is relative to N4917.

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

    namespace std {
    template
    class basic_format_args {
    size_t size_; // exposition only
    const basic_format_arg* 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 get(size_t i) const noexcept;
};

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