I throw away the alternative (but I think the @Piotr solution will be more elegant).
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, "!" ); }