2014-10-24 2 views
2

Как связать два кортежа? НапримерКак связать два кортежа?

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) сначала развязывает кортежи, а затем связывает все элементы вместе.

+0

И что именно вы хотели? – Cornstalks

+0

'tie (a, b)'? Какой прецедент? – user657267

+0

'std :: tie' выравнивает тип по причине: проще использовать его таким образом, и не менее общим. – Deduplicator

ответ

3

(Обновлено 29 декабря 2014 использовать std::index_sequence_for)

Вот решение, которое использует 14 C++ в индексных последовательности:

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

'std :: index_sequence_for ' показывает какую-то ошибку, если T - пустой пакет с версией CLL-LLVM от clang-Apple, а 'std :: make_index_sequence ' отлично работает для всех случаев. –

3

Чуть более общие, чем @ версия Брайана:

// 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.

Смежные вопросы