DmitryKoterov
@DmitryKoterov

С++0: итерация по контейнеру с применением callback-а и возвратом результата (а-ля Perl map{})

После многочасовых экспериментов удалось догадаться только вот до такого:

template<typename V, typename Cb> 
auto apply(V vec, Cb&& callback) -> vector<decltype(callback(*vec.begin()))>
{
    vector<decltype(callback(*vec.begin()))> result;
    for (auto &e: vec) result.push_back(callback(e));
    return result;
}

// Использование:
map<string, string> hash;
auto result = apply(hash, [](const pair<string,string>& e) { return e.first + "=>" + e.second; });

Нет ли более изящного решения? А то decltype(callback(*vec.begin())) в заголовке функции — просто жесть, но по-другому никак не получается (в том числе и через result_of).

P.S.
Вообще, удивительно, в Perl'е (да и в других языках) функции типа map и grep очень популярны, но все мои попытки найти аналоги в C++0x не увенчались успехом — вот, пришлось придумать такую страшилу.
  • Вопрос задан
  • 2538 просмотров
Пригласить эксперта
Ответы на вопрос 3
afiskon
@afiskon
Ответ написан
Комментировать
Paul
@Paul
std::transform(vec.begin(), vec.end(), std::back_inserter(result), callback)

Без всяких С++0x. Или я неверно понял, что требуется сделать?
Ответ написан
Комментировать
DmitryKoterov
@DmitryKoterov Автор вопроса
for_each итерирует, но НЕ ВОЗВРАЩАЕТ результат, а применяет его «на месте».
std::transform же работает с итераторами (т.е. тоже ничего не возвращает).
Так что это не то.

Я понимаю, что в 2 строчки можно записать (вначале — определить массив-результат пустой, а затем — через for_each или transform его заполнить). Но некрасиво же, хочется, как в Perl — cout<<join(apply(hash, [](const pair<string,string>& e) { return e.first + "=>" + e.second; }), "\n");
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы