произвольную функцию к объектам кортежа
template <class Tuple, class F, std::size_t... I>
constexpr F for_each_impl(Tuple&& t, F&& f, std::index_sequence<I...>) {
return (void)std::initializer_list<int>{(std::forward<F>(f)(std::get<I>(std::forward<Tuple>(t))),0)...}, f;
}
template <class Tuple, class F>
constexpr F for_each_(Tuple&& t, F&& f) {
return for_each_impl(std::forward<Tuple>(t), std::forward<F>(f),
std::make_index_sequence<std::tuple_size<std::remove_reference_t<Tuple>>::value>{});
}
Собственно, вопрос - как прочитать строку возврата?
return (void)std::initializer_list<int>{(std::forward<F>(f)(std::get<I>(std::forward<Tuple>(t))),0)...}, f;
я чего-то въехать не могу, кастуем список инициализации к void и через запятую указатель на функцию просто упоминаем?
Применяется раскрытие пака на выражение (std::get<I>(std::forward<Tuple>(t))), 0) Оператор запятая возвращает последний операнд, при этом вычисляя все подвыражения
Это из > C++17-времен, видимо, когда fold-expr не было, а упорядоченно вычислить хотелось. Раскрытие пака в инициализатор позволяет вычислить условный f(t[i], 0) в порядке аргументов инициализатора (и порядке индексов последовательности по совместительству). Сама функция возвращается по интерфейсному контракту (оператор "запятая" вычисляет подвыражения слева-направо, возвращая последнее).
Применяется раскрытие пака на выражение (std::forward<F>(f)(std::get<I>(std::forward<Tuple>(t))),0) А на именно на это выражение (std::get<I>(std::forward<Tuple>(t))), 0) Оператор запятая возвращает последний операнд, при этом вычисляя все подвыражения. Т.е. выглядит в конечном счете, опустив форварды и прочее, это примерно так: (F(tuple_elements), 0)... В итоге получается, что собирается initializer list из нулей, при этом вычисляется выражение F(tuple_elements)...
А зачем все так сложно то…
Чуть выше, тов. Sergey написал, зачем)
Да я пытаюсь развернуть parameter pack, вот собираюсь реверснуть кортеж, который из пака делаю. Других идей нет.
У вас какой стандарт языка?
Обсуждают сегодня