Ankit Thakar
Ankit Thakar

Reputation: 43

Transform using range-v3

I am trying below code using ranges but it doesn't working.

// Code
std::map<int, std::string> m{ {1,"foo"},{42,"bar"},{7,"baz"} };
std::vector<int> keys;

// without using ranges
std::transform(begin(m), end(m), std::back_inserter(keys), [](auto val)
{
    return val.first;
});

which is working fine. But,

// with using ranges
ranges::transform(m,std::back_inserter(keys), [](auto val)
{
    return val.first;
});

it is not working with ranges??

I am using MSVC 2017 15.9.14

Upvotes: 3

Views: 1855

Answers (1)

lubgr
lubgr

Reputation: 38267

The range-v3 doesn't support std::back_insert_iterator, because it doesn't satisfy the library Iterator concept, see this issue. As it's pointed out in the discussion, this is supposed to be fixed with C++20.

You can fix this by either

keys.resize(3);

ranges::transform(m, keys.begin(), [](auto val) { return val.first; });

or, in my opinion preferable (as you can make keys const):

const std::vector<int> keys = m |
    ranges::view::transform([](auto val){ return val.first; });

As a side note, consider passing the lambda parameter as a const-qualified reference to avoid unnecessary copies.

Upvotes: 4

Related Questions