How do I create a tuple of N T's from an array of T? How do I create a tuple of N T's from an array of T? arrays arrays

How do I create a tuple of N T's from an array of T?


Here is a possible implementation for raw arrays:

#include<functional>template<std::size_t... I, std::size_t N>constexpr auto f(const int (&arr)[N], std::index_sequence<I...>) {    return std::make_tuple(arr[I]...);}template<std::size_t N>constexpr auto f(const int (&arr)[N]) {    return f(arr, std::make_index_sequence<N>{});}int main() {    constexpr int arr[] = { 0, 1, 2 };    constexpr auto tup = f(arr);    static_assert(std::get<0>(tup) == 0, "!");    static_assert(std::get<1>(tup) == 1, "!");    static_assert(std::get<2>(tup) == 2, "!");}

The size of a constexpr array can be deduced at compile-time, so you don't have to explicitly specify it.
That size can be used internally to create a set of indices to get the elements out from the array and create the tuple on the fly.


As mentioned in the comments, if you want to generalize a bit more and accept both raw arrays and std::arrays, you can do this:

#include<functional>#include<array>template<std::size_t... I, typename U>constexpr auto f(const U &arr, std::index_sequence<I...>) {    return std::make_tuple(arr[I]...);}template<typename T, std::size_t N>constexpr auto f(const T (&arr)[N]) {    return f(arr, std::make_index_sequence<N>{});}template<typename T, std::size_t N>constexpr auto f(const std::array<T, N> &arr) {    return f(arr, std::make_index_sequence<N>{});}int main() {    constexpr int arr1[] = { 0, 1, 2 };    constexpr auto tup1 = f(arr1);    static_assert(std::get<0>(tup1) == 0, "!");    static_assert(std::get<1>(tup1) == 1, "!");    static_assert(std::get<2>(tup1) == 2, "!");    constexpr std::array<int, 3> arr2 = { 0, 1, 2 };    constexpr auto tup2 = f(arr2);    static_assert(std::get<0>(tup2) == 0, "!");    static_assert(std::get<1>(tup2) == 1, "!");    static_assert(std::get<2>(tup2) == 2, "!");}


Converting an array into a tuple takes advantage of std::integer sequence, building up the array indices at compile time as the compiler invokes the helper function for 0..N.

Here's the code which demonstrates this.http://coliru.stacked-crooked.com/a/b2d6c6ca1f5dc635

////////////////////////////////////////////////////////////////////////////////////////////////////// tuple_from_arraynamespace detail {template<typename T, std::size_t... Is>auto constexpr tuple_from_array(T const& arr, std::index_sequence<Is...>){  return std::make_tuple(arr[Is]...);}template<std::size_t N, typename V, typename T, std::size_t ...Is>auto constexpr array_from_container(T const& c, std::index_sequence<Is...>){  return std::array<V, N>{c[Is]...};}} // ns detailtemplate<typename T>auto constexpr tuple_from_array(T const& arr){  auto constexpr tup_size = std::tuple_size<std::decay_t<T>>::value;  return detail::tuple_from_array(arr, std::make_index_sequence<tup_size>{});}template<typename T, std::size_t N>auto constexpr tuple_from_array(T const (&arr)[N]){  return detail::tuple_from_array(arr, std::make_index_sequence<N>{});}// not safetemplate<std::size_t N, typename T>auto constexpr tuple_from_container(T const& c){  using V = typename T::value_type;  return tuple_from_array(detail::array_from_container<N, V>(c, std::make_index_sequence<N>{}));}

edit: I combined skypjack@'s answer with my own to cover basic arrays as queried in the comments. I can't re-put this as my own answer for two days though :(