Может кто-нибудь объяснить "трюк индексов"?

Я заметил, что "трюк индексов" упоминается в контексте довольно печатных кортежей. Это звучало интересно, поэтому я следил за ссылкой.

Ну, это не здорово. Я понял этот вопрос, но не мог не следовать тому, что происходило. Почему нам даже нужны индексы? Как различные функции, определенные там, помогают нам? Что такое "Bare"? и др.

Может ли кто-нибудь дать поэтапную игру этой вещи для менее чем экспертов по пакетам параметров и вариационным кортежам?

Ответ 1

Проблема заключается в следующем: мы имеем std::tuple<T1, T2, ...>, и у нас есть некоторая функция f, которую мы можем вызвать для каждого элемента, где f возвращает int, и мы хотим сохранить эти результаты в массиве,

Начнем с конкретного случая:

template <typename T> int f(T ) { return sizeof(T); }

std::tuple<int, char, double> tup{42, 'x', 3.14};
std::array<int, 3> arr{ f(std::get<0>(tup)), 
                        f(std::get<1>(tup)),
                        f(std::get<2>(tup)) );

За исключением того, что все эти get неудобны и избыточны в лучшем случае, подвержены ошибкам в худшем случае. Теперь предположим, что у нас был тип index_sequence<0, 1, 2>. Мы могли бы использовать это, чтобы свернуть эту инициализацию массива в расширение вариационного пакета:

template <typename Tuple, size_t... Indices>
std::array<int, sizeof...(Indices)> 
call_f_detail(Tuple& tuple, index_sequence<Indices...> ) {
    return { f(std::get<Indices>(tuple))... };
}

Это потому, что внутри функции f(std::get<Indices>(tuple))... расширяется до f(std::get<0>(tuple)), f(std::get<1>(tuple)), f(std::get<2>(tuple)). Это именно то, что мы хотим.

Последняя деталь проблемы - это просто генерация определенной последовательности индексов. С++ 14 действительно дает нам такую ​​утилиту с именем make_index_sequence

template <typename Tuple>
std::array<int, std::tuple_size<Tuple>::value>
call_f(Tuple& tuple) {
    return call_f_detail(tuple,
        // make the sequence type sequence<0, 1, 2, ..., N-1>
        std::make_index_sequence<std::tuple_size<Tuple>::value>{}
        );
}

в то время как статья, которую вы указали, просто объясняет, как можно реализовать такой метафорум.

Bare, вероятно, что-то вроде Luc Danton answer:

template<typename T>
using Bare = typename std::remove_cv<typename std::remove_reference<T>::type>::type;