2814. [fund.ts.v2] to_array should take rvalue reference as well

Section: 99 [fund.ts.v2::func.wrap.func.con] Status: LEWG Submitter: Zhihao Yuan Opened: 2016-11-07 Last modified: 2017-06-10

Priority: 3

View all other issues in [fund.ts.v2::func.wrap.func.con].

View all issues with LEWG status.

Discussion:

Addresses: fund.ts.v2

C++ doesn't have a prvalue expression of array type, but rvalue arrays can still come from different kinds of sources:

  1. C99 compound literals (int[]) {2, 4},

  2. std::move(arr),

  3. Deduction to_array<int const>({ 2, 4 }).

    See also CWG 1591: Deducing array bound and element type from initializer list.

For 3), users are "abusing" to_array to get access to uniform initialization to benefit from initializing elements through braced-init-list and/or better narrowing conversion support.

We should just add rvalue reference support to to_array.

[Issues Telecon 16-Dec-2016]

Status to LEWG

[2017-02 in Kona, LEWG responds]

Would like a small paper; see examples before and after. How does this affect overload resolution?

[2017-06-02 Issues Telecon]

Leave status as LEWG; priority 3

Proposed resolution:

This wording is relative to N4600.

  1. Add the following signature to [fund.ts.v2::header.array.synop]:

    // 9.2.2, Array creation functions
    template <class D = void, class... Types>
      constexpr array<VT, sizeof...(Types)> make_array(Types&&... t);
    template <class T, size_t N>
      constexpr array<remove_cv_t<T>, N> to_array(T (&a)[N]);
    template <class T, size_t N>
      constexpr array<remove_cv_t<T>, N> to_array(T (&&a)[N]);
    
  2. Modify [fund.ts.v2::container.array.creation] as follows:

    template <class T, size_t N>
      constexpr array<remove_cv_t<T>, N> to_array(T (&a)[N]);
    template <class T, size_t N>
      constexpr array<remove_cv_t<T>, N> to_array(T (&&a)[N]);
    

    -6- Returns: For all i, 0 ≤ i < N, aAn array<remove_cv_t<T>, N> such that each element is copy-initialized with the corresponding element of ainitialized with { a[i]... } for the first form, or { std::move(a[i])... } for the second form..