Is there and neat equivalent to view a member function/variable?
Asked Answered
P

1

5

Streams library has a neat map function to view a range by a member function. Is there any equivalent view in Range-V3?

Would view::transform be the only option?

Poisonous answered 17/3, 2015 at 22:25 Comment(0)
P
8

The example from the article:

std::vector widgets = /* ... */    
std::set ids = stream::MakeStream::from(widgets)
         .map(&Widget::getId)
         .to_set();

(ignoring the missing template arguments for std::vector and std::set) in ranges-v3 would be:

std::vector<Widget> widgets = // ...
std::set<Widget::ID> ids = widgets | ranges::view::transform(&Widget::getId);

Yes, transform is the equivalent to map in Streams.

All the algorithms in range-v3 accept Invokable Projections that allow enable the algorithm to select range elements on the basis of a transformation, but still operate on the entire element. For example, we can sort the Widgets by their IDs:

widgets |= ranges::action::sort(std::greater<Widget::ID>{}, &Widget::getId);
Penn answered 18/3, 2015 at 3:11 Comment(5)
Thank you. Conceptually speaking I think that there should be some sort of difference between transform and select. A transformation seems like something that processes the data of some way. (ie ...view::transform([](arg0) { return arg0*arg0; }) ) or similar.Poisonous
There is no logical distinction between "select" and "transform". Why have two views when one will do? Also, no need to use an action, Casey. The algorithm works fine: ranges::sort(widgets, std::greater<Widget::ID>{}, &Widget::getId);Blocker
@EricNiebler Thinking about it, youre absolutely correct, I take it back 100%Poisonous
Thinking about it; something like #define SELECT(pMember) ranges::view::transform([](const auto& val) { return val.pMember; }) yielding auto ids = widgets | SELECT(getId()); would still be pretty sweet.Poisonous
I dont think it could be achieved without a macro thou.Poisonous

© 2022 - 2024 — McMap. All rights reserved.