Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert std::tuple to std::array C++11

Tags:

If I have std::tuple<double, double, double> (where the type is homogeneous), is there a stock function or constructor to convert to std::array<double>?

Edit:: I was able to get it working with recursive template code (my draft answer posted below). Is this the best way to handle this? It seems like there would be a stock function for this... Or if you have improvements to my answer, I'd appreciate it. I'll leave the question unanswered (after all, I want a good way, not just a workable way), and would prefer to select someone else's [hopefully better] answer.

Thanks for your advice.

like image 972
user Avatar asked May 15 '12 16:05

user


2 Answers

Converting a tuple to an array without making use of recursion, including use of perfect-forwarding (useful for move-only types):

#include <iostream> #include <tuple> #include <array>  template<int... Indices> struct indices {     using next = indices<Indices..., sizeof...(Indices)>; };  template<int Size> struct build_indices {     using type = typename build_indices<Size - 1>::type::next; };  template<> struct build_indices<0> {     using type = indices<>; };  template<typename T> using Bare = typename std::remove_cv<typename std::remove_reference<T>::type>::type;  template<typename Tuple> constexpr typename build_indices<std::tuple_size<Bare<Tuple>>::value>::type make_indices() { return {}; }  template<typename Tuple, int... Indices> std::array<   typename std::tuple_element<0, Bare<Tuple>>::type,     std::tuple_size<Bare<Tuple>>::value > to_array(Tuple&& tuple, indices<Indices...>) {     using std::get;     return {{ get<Indices>(std::forward<Tuple>(tuple))... }}; }  template<typename Tuple> auto to_array(Tuple&& tuple) -> decltype( to_array(std::declval<Tuple>(), make_indices<Tuple>()) ) {     return to_array(std::forward<Tuple>(tuple), make_indices<Tuple>()); }  int main() {   std::tuple<double, double, double> tup(1.5, 2.5, 4.5);   auto arr = to_array(tup);   for (double x : arr)     std::cout << x << " ";   std::cout << std::endl;   return 0; } 
like image 79
Luc Danton Avatar answered Sep 23 '22 01:09

Luc Danton


The C++17 solution is a short one:

template<typename tuple_t> constexpr auto get_array_from_tuple(tuple_t&& tuple) {     constexpr auto get_array = [](auto&& ... x){ return std::array{std::forward<decltype(x)>(x) ... }; };     return std::apply(get_array, std::forward<tuple_t>(tuple)); } 

Use it as

auto tup = std::make_tuple(1.0,2.0,3.0); auto arr = get_array_from_tuple(tup); 

EDIT: forgot to sprinkle constexpr anywhere :-)

like image 32
davidhigh Avatar answered Sep 23 '22 01:09

davidhigh