Как извлечь значение из пакета параметров шаблона переменной по индексу?

Я хочу написать функцию magic_get, который может извлечь значение из пакета параметров по индексу, например:

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);

Как реализовать magic_get?

4

Решение

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)...));
}

+ Изменить decltype(auto) в auto и добавить конечный тип возврата decltype(/* the whole returned expression here */) если функции C ++ 14 недоступны.


Бестолковая версия:

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)...);
}

Обратите внимание, что это не работает в Clang, благодаря лягушка ошибка 11723. Замена std::enable_if_t<N != 0, int>... с std::enable_if_t<N != 0, int> = 0 это простой обходной путь.

14

Другие решения