D
D
DmitryKoterov2011-06-18 17:11:24
C++ / C#
DmitryKoterov, 2011-06-18 17:11:24

C++0: iterating over a container using a callback and returning a result (a la Perl map{})

After many hours of experimenting, I managed to guess only this:

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

// Usage:
map<string, string> hash;
auto result = apply(hash, [](const pair<string,string>& e) { return e.first + "=>" + e.second; });

Is there a more elegant solution? And then decltype(callback(*vec.begin())) in the function header is just tin, but it doesn’t work in any other way (including through result_of).

PS
In general, surprisingly, in Perl (and in other languages ​​as well) functions like map and grep are very popular, but all my attempts to find analogues in C ++ 0x were unsuccessful - so, I had to come up with such a scarecrow.

Answer the question

In order to leave comments, you need to log in

3 answer(s)
A
afiskon, 2011-06-18
@afiskon

for_each(...) www.cplusplus.com/reference/algorithm/for_each/

P
Paul, 2011-06-18
@Paul

std::transform(vec.begin(), vec.end(), std::back_inserter(result), callback)

Without any C++0x. Or did I misunderstand what needs to be done?

D
DmitryKoterov, 2011-06-18
@DmitryKoterov

for_each iterates, but DOES NOT RETURN the result, but applies it "in place".
std::transform works with iterators (i.e. it doesn't return anything either).
So that's not it.
I understand that it can be written in 2 lines (first, define the result array empty, and then fill it through for_each or transform). But it’s ugly, I want it, like in Perl - cout<<join(apply(hash, [](const pair<string,string>& e) { return e.first + "=>" + e.second; }), "\n");

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question