std::to_array - cppreference.com

From cppreference.com

Defined in header

<array>

template<classT,std::size_tN>constexprstd::array<std::remove_cv_t<T>,N>to_array(T(&a)[N]); (1)(since C++20)template<classT,std::size_tN>constexprstd::array<std::remove_cv_t<T>,N>to_array(T(&&a)[N]); (2)(since C++20)Creates a

std::array

from the one dimensional built-in array a. Copying or moving multidimensional built-in array is not supported.

1) For every i in 0, ..., N - 1, copy-initializes result's correspond element with a[i]. This overload is ill-formed when std::is_constructible_v<T,T&> is false.

2) For every i in 0, ..., N - 1, move-initializes result's correspond element with std::move(a[i]). This overload is ill-formed when std::is_move_constructible_v<T> is false.

Both overloads are ill-formed when std::is_array_v<T> is true.

Parameters

a - the built-in array to be converted the

std::array

Type requirements -T must meet the requirements of

CopyConstructible

in order to use overload (1). -T must meet the requirements of

MoveConstructible

in order to use overload (2). Return value

1){{a[0],...,a[N-1]}}

2){{std::move(a[0]),...,std::move(a[N-1])}}

Notes

There are some occasions where

class template argument deduction

of

std::array

cannot be used while to_array is available:

to_array can be used when the element type of the std::array is manually specified and the length is deduced, which is preferable when implicit conversion is wanted.

to_array can copy a string literal, while class template argument deduction constructs a std::array of a single pointer to its first character.

std::to_array<long>({3,4});// OK: implicit conversion// std::array<long>{3, 4}; // error: too few template argumentsstd::to_array("foo");// creates std::array<char, 4>{'f', 'o', 'o', '\0'}std::array{"foo"};// creates std::array<const char*, 1>{"foo"}

Feature-test

macroValueStdFeature

__cpp_lib_to_array

201907L

(C++20)std::to_arrayPossible implementation

to_array (1)

namespacedetail{template<classT,std::size_tN,std::size_t...I>constexprstd::array<std::remove_cv_t<T>,N>to_array_impl(T(&a)[N],std::index_sequence<I...>){return{{a[I]...}};}}template<classT,std::size_tN>constexprstd::array<std::remove_cv_t<T>,N>to_array(T(&a)[N]){returndetail::to_array_impl(a,std::make_index_sequence<N>{});}

to_array (2)

namespacedetail{template<classT,std::size_tN,std::size_t...I>constexprstd::array<std::remove_cv_t<T>,N>to_array_impl(T(&&a)[N],std::index_sequence<I...>){return{{std::move(a[I])...}};}}template<classT,std::size_tN>constexprstd::array<std::remove_cv_t<T>,N>to_array(T(&&a)[N]){returndetail::to_array_impl(std::move(a),std::make_index_sequence<N>{});}Example

Run this code

#include<array>#include<memory>#include<string_view>#include<type_traits>#include<utility>// creates a constexpr array of string_view's constexprautow1n=std::to_array<std::string_view>({"Mary","Patricia","Linda","Barbara","Elizabeth","Jennifer"});static_assert(std::is_same_v<decltype(w1n),conststd::array<std::string_view,6>>);static_assert(w1n.size()==6andw1n[5]=="Jennifer");intmain(){// copies a string literalautoa1=std::to_array("foo");static_assert(a1.size()==4);// deduces both element type and lengthautoa2=std::to_array({0,2,1,3});static_assert(std::is_same_v<decltype(a2),std::array<int,4>>);// deduces length with element type specified// implicit conversion happensautoa3=std::to_array<long>({0,1,3});static_assert(std::is_same_v<decltype(a3),std::array<long,3>>);autoa4=std::to_array<std::pair<int,float>>({{3,0.0f},{4,0.1f},{4,0.1e23f}});static_assert(a4.size()==3);// creates a non-copyable std::arrayautoa5=std::to_array({std::make_unique<int>(3)});static_assert(a5.size()==1);// error: copying multidimensional arrays is not supported// char s[2][6] = {"nice", "thing"};// auto a6 = std::to_array(s);}See also

(library fundamentals TS v2)

creates a

std::array

object whose size and optionally element type are deduced from the arguments
(function template)

[edit]