Ich werfe eine Alternative auf (aber ich denke, dass @ Piotrs Lösung eleganter zu sein).
template <size_t ...>
struct seq { };
// X, Y are the indeces we want to swap
template <size_t N, size_t X, size_t Y, size_t ...S>
struct gen : gen<N-1, X, Y, (N-1 == X ? Y : (N-1 == Y ? X : N - 1)), S...> { };
template <size_t X, size_t Y, size_t ...S>
struct gen<0, X, Y, S...> {
typedef seq<S...> type;
};
// X and Y are the index we want to swap, T is the tuple
template <size_t X, size_t Y, class T, class S>
struct swapImpl;
template <size_t X, size_t Y, class T, size_t... S>
struct swapImpl<X, Y, T, seq<S...>>{
using type = std::tuple<typename std::tuple_element<S, T>::type...>;
};
template <size_t X, size_t Y, class T>
struct swap {
using type = typename swapImpl<X, Y, T,
typename gen<std::tuple_size<T>::value, X, Y>::type>::type;
};
int main() {
using tuple_t = std::tuple<int, unsigned, void, char, double>; // int, void, double
using swapped_tuple_a_t = std::tuple<unsigned, int, void, char, double>; // double, void, int
static_assert(std::is_same<swap<0, 1, tuple_t>::type, swapped_tuple_a_t>::value, "!");
static_assert(std::is_same<swap<1, 0, tuple_t>::type, swapped_tuple_a_t>::value, "!");
using swapped_tuple_b_t = std::tuple<int, char, void, unsigned, double>; // double, void, int
static_assert(std::is_same<swap<1, 3, tuple_t>::type, swapped_tuple_b_t>::value, "!");
static_assert(std::is_same<swap<3, 1, tuple_t>::type, swapped_tuple_b_t>::value, "!");
}
Wusste nicht über 'std :: make_index_sequence'. Schöne, saubere Lösung. – simpel01
@MarcoA. Gut, um Probleme aufzuzeigen, aber es ist keine große Sache, da 'swap <2, 0>' nur in 'swap <0, 2>' umgewandelt werden kann. – user2296177
@ user2296177 ja, der Code vor der Bearbeitung fehlgeschlagen für 'swap' mit 'x> = y' .. trotzdem frage ich mich nur, wie kommt es nicht mit 'libC++' –