C++:获取参数包的头和尾

Chi*_*Lin 5 c++ templates variadic parameter-pack

如何获取参数包的前n个元素?或者最后 n 个元素,或者 [n, n+1, ..., m) 中的一片元素?例如:

head<3>(1, 2.0f, "three", '4') => make_tuple(1, 2.0f, "three")
tail<2>(1, 2.0f, "three", '4') => make_tuple("three", '4')
slice<1,3>(1, 2.0f, "three", '4') => make_tuple(2.0, "three")
Run Code Online (Sandbox Code Playgroud)

这可以通过 std::tuple、std::integer_sequence 和 std::get 的组合来实现,但我想知道是否有更简单的方法。

Ide*_*Hat 1

#include <tuple>

using namespace std;

template <size_t offset, typename Tuple, size_t... N>
auto GetRange(Tuple&& t, std::index_sequence<N...>) {
    return std::make_tuple(std::get<offset+N>(std::forward<Tuple>(t))...);
}

template <size_t N, typename... T>
auto Head(T&&... t) {
    return GetRange<0>(
        std::make_tuple(std::forward<T>(t)...),
        std::make_index_sequence<N>{});
}

template <size_t N, typename... T>
auto Tail(T&&... t) {
    return GetRange<N>(
        std::make_tuple(std::forward<T>(t)...),
        std::make_index_sequence<
        sizeof...(T)-N
        >{});
}

template <int N>
struct PrintTupleElementHelper {
template <typename Tup>
static void Do(const Tup& t) {
    PrintTupleElementHelper<N-1>::Do(t);
    cout << std::get<N>(t) << ',';
}

};

template <>
struct PrintTupleElementHelper<0> {
template <typename Tup>
static void Do(const Tup& t) {
    cout << std::get<0>(t) << ',';
}

};

template <typename Tup>
void PrintTupleElement(const Tup& t) {
    PrintTupleElementHelper<std::tuple_size<Tup>{}-1>::Do(t);
    cout << endl;
}

int main() {
    // your code goes here
    PrintTupleElement(Head<3>("Foo", 10, 'x', "Baz"));
    PrintTupleElement(Tail<3>("Foo", 10, 'x', "Baz"));
    
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

第一个相当简单,最后一个考虑到拆包规则则有点棘手。您可以使用 rhr 来提高效率。