Reputation: 13575
How to tie two tuples? For example
std::tuple<int, char> a;
std::tuple<double> b;
Is it possible to write a function my_tie(a, b)
that returns std::tuple<int&, char&, double&>
so that after
my_tie(a, b) = make_tuple(1, 'a', 3.14);
a == std::tuple<int, char>{1, 'a'}
and b == std::tuple<double>{3.14}
. That is, the my_tie
function (different from std::tie) first unties the tuples and then ties all elements together.
Upvotes: 3
Views: 353
Reputation: 119641
(Updated Dec 29, 2014 to use std::index_sequence_for
)
Here's a solution that uses C++14's index sequences:
#include <tuple>
#include <utility>
template <class... T1, class... T2,
std::size_t... i, std::size_t... j>
auto tie_helper(std::tuple<T1...>& t1, std::tuple<T2...>& t2,
std::index_sequence<i...>, std::index_sequence<j...>) {
return std::tuple<T1&..., T2&...> {std::get<i>(t1)..., std::get<j>(t2)...};
}
template <class... T1, class... T2>
auto tie(std::tuple<T1...>& t1, std::tuple<T2...>& t2) {
typedef std::index_sequence_for<T1...> s1;
typedef std::index_sequence_for<T2...> s2;
return tie_helper(t1, t2, s1{}, s2{});
}
Upvotes: 3
Reputation: 137414
Slightly more general than @Brian's version:
// construct a tuple of Ts&... from a tuple of Ts...
template <class... T, std::size_t... i>
auto to_tuple_ref_helper(std::tuple<T...>& t, std::index_sequence<i...>) {
return std::tuple<T&...> {std::get<i>(t)...};
}
template <class... T>
auto to_tuple_ref(std::tuple<T...>& t) {
return to_tuple_ref_helper(t, std::index_sequence_for<T...>());
}
// and a tuple containing a single reference from all other types
template <class T>
auto to_tuple_ref(T& t) {
return std::tuple<T&>{t};
}
// tuple_cat the tuples of references together
template <class... Ts>
auto flattening_tie(Ts &...args) {
return std::tuple_cat(to_tuple_ref(args)...);
}
Demo.
Upvotes: 3