How to extract a value from a variadic template parameter pack by index?

c++, c++11, compile-time-constant, templates, variadic-templates

Solution

template <size_t N, typename... Args>
decltype(auto) magic_get(Args&&... as) noexcept {
    return std::get<N>(std::forward_as_tuple(std::forward<Args>(as)...));
}

Change `decltype(auto)` to `auto` and add a trailing return type of `decltype(/* the whole returned expression here */)` if C++14 features are unavailable.

Tupleless version:

template <std::size_t N, typename Tfirst, typename... Args, std::enable_if_t<N == 0, int>...>
decltype(auto) magic_get(Tfirst&& first, Args&&... as) noexcept {
    return std::forward<Tfirst>(first);
}

template <std::size_t N, typename Tfirst, typename... Args, std::enable_if_t<N != 0, int>...>
decltype(auto) magic_get(Tfirst&& first, Args&&... as) noexcept {
    return magic_get<N - 1>(std::forward<Args>(as)...);
}

Note that this does not work in clang, thanks to clang bug 11723. Replacing `std::enable_if_t<N != 0, int>...` with `std::enable_if_t<N != 0, int> = 0` is a simple workaround.

Problem

I want to write a function `magic_get`, which can extract a value from a parameter pack by index, for example: ``` int n = 0; n = magic_get<0>(1, 3, 5, 7); assert(1 == n); n = magic_get<1>(1, 3, 5, 7); assert(3 == n); n = magic_get<2>(1, 3, 5, 7); assert(5 == n); n = magic_get<3>(1, 3, 5, 7); assert(7 == n); ``` How to implement `magic_get`?

Original source