Как стать автором
Обновить

Комментарии 11

foreach, кстати, можно и короче сделать:
template <typename F, typename T, size_t... i>
void tupleForeachImpl(F&& f, T&& t, index_sequence<i...>) {
    auto unused = { (f(get<i>(forward<T>(t))), true)... };
}

template <typename F, typename T>
void tupleForeach(F&& f, T&& t) {
    tupleForeachImpl(forward<F>(f), forward<T>(t), make_index_sequence<tuple_size<typename decay<T>::type>::value>());
}

Но это уже для любителей.
И лучше всё-таки использовать универсальные ссылки и forward, а не const &, при передаче функторов и кортежей.

Раз уж такая пьянка:


  1. Не учитываются пустые тюплы, нужно, для unused, хотя бы 1н элемент
  2. Не учитывается перегруженный operator,() для случая, когда F возвращает user-defined тип, для которого и определён operator,()
  3. Раз уж C++ 14, тогда и decay_t<T> вместо typename decay<T>::type (tuple_size_v можно аналогично заюзать, но уже C++ 17)
  4. decay<T> — слишком жёстко, просто — remove_reference<T>

template <typename F, typename T, size_t... i>
void tupleForeachImpl(F&& f, T&& t, index_sequence<i...>) {
    auto unused = { true, (f(get<i>(forward<T>(t))), void(), true)... };
}

template <typename F, typename T>
void tupleForeach(F&& f, T&& t) {
    tupleForeachImpl(forward<F>(f), forward<T>(t), make_index_sequence<tuple_size<remove_reference_t<T>>::value>());
}

Ну и, я думаю, стоило бы упомянуть C++ 17 fold expressions

Буквально пару недель назад тоже понадобился foreach для tuple. Сделал на основе варианта со StackOverflow идеологически схожего с вашим. Но остался вопрос, почему ..., void(), а не static_cast<void>(...)? Вкусовщина или есть нюансы?

да, дело вкуса, разници нет. Лично я думаю, что static_cast() — слишком длинно, C-style каст — слишком незаметно, а странный void() — и в глаза падает (идешь гуглить, что это за void()), и не слишком длинный

Что это за магия? Зачем надо использовать true и void() в initilizer_list ???
если честно, не понял, зачем там void().
разве для составления unused (который по сути можно объявить как bool unused[] =) не достаточно будет только параметра true?

Так написано же, что это защита от перегруженного operator,().

И лучше всё-таки использовать универсальные ссылки и forward, а не const &
Соглашусь. Весьма небрежно с моей стороны.
Блин, какой же C++ уродливый… Я не хочу писать на таком языке. Я должен выкинуть свои 20 лет на попытки понять этот язык и перейти на что-нибудь другое. Я сдаюсь.

Не вы одни сдаётесь. Вон, Мейерс тоже сдался. Но это еще не означает, что C++ — уродливый. Вы на новые стандарты C — посмотрите. Там тоже можно за голову взяться. Это нормально для языков с историей, которые еще и развиваются

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории