如何将两个元组合并?

3
如何将两个元组连接起来?例如:
std::tuple<int, char> a;
std::tuple<double> b;

能否编写一个函数my_tie(a, b),返回std::tuple<int&, char&, double&>类型的结果,以便在执行以下代码后:

my_tie(a, b) = make_tuple(1, 'a', 3.14);

a == std::tuple<int, char>{1, 'a'}b == std::tuple<double>{3.14}。也就是说,my_tie函数(与std::tie不同)首先解开元组,然后将所有元素绑定在一起。


你到底想要什么? - Cornstalks
tie<decltype(a), decltype(b)>(a, b)的用途是什么? - user657267
std::tie将类型展平是有原因的:这样使用更容易,而且不会降低其通用性。 - Deduplicator
1
你能否请重新表述你的问题?目前的表述让人无法理解你是在声称 tie 会将 tuple 扁平化(实际上它不会,参见 http://coliru.stacked-crooked.com/a/1e985b7792db0c5a),还是你*希望*它将它们扁平化。 - Praetorian
@Praetorian,我想构建我的 tie 函数(不同于 std::tie),该函数将首先解开元组,然后将所有元素绑定在一起。 - user1899020
2个回答

3

(已更新于2014年12月29日,使用std::index_sequence_for)

下面是一个使用C++14的索引序列的解决方案:

#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{});
}

如果T是一个空包,使用clang-Apple LLVM版本7.0.0时,std::index_sequence_for<T...>会显示某种错误,而std::make_index_sequence<sizeof...<T>>在所有情况下都可以正常工作。 - Utkarsh Bhardwaj

3
略微更加通用的版本,比 @Brian 的版本更好:
// 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.


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接