4

Suppose I have a std::vector of std::pairs, then I can using c++20 constrained algorithm's projection facility to sort elements according to sub-object:

std::vector<std::pair<int, std::string>> v;
// sort by std::string
ranges::sort(v, {}, &std::pair<int, std::string>::second);

but how to do nested projection like this?

// sort by std::string::size
ranges::sort(v, {}, &std::pair<int, std::string>::second::size);
康桓瑋
  • 33,481
  • 5
  • 40
  • 90
  • 1
    Just use `[](const std::pair& elem) { return elem.second.size(); }` for the projection. – Igor Tandetnik Dec 14 '20 at 15:26
  • @IgorTandetnik Stack Overflow is a Q&A, so although it has comments sections, those are reserved for requesting clarification and for arguing with people. Please answer questions in the answer area below where it can be peer reviewed. Thanks! – Asteroids With Wings Dec 14 '20 at 15:30
  • You can't create pointers to nested data members, and so unfortunately you can't provide a projection that's nested. – cigien Dec 14 '20 at 16:04
  • @cigien Uh, yes you can, see my answer. – Barry Dec 14 '20 at 17:33
  • @Barry I'm not sure I understand. You wrote a lambda to get at the value, which is of course possible. IIUC, OP is asking for how to write `&A::B::C` specifically, which is not possible, and is covered in the target. – cigien Dec 14 '20 at 18:00
  • @cigien That's not how I interpret the question... It's just how do you do a nested projection? – Barry Dec 14 '20 at 18:03
  • @Barry Yeah, that's fair. And since the OP accepted your answer, that must be what they want. Ok then, and thanks for messaging to let me know. – cigien Dec 14 '20 at 18:07

1 Answers1

5

The projection is just an arbitrary callable. Providing a pointer to member is convenient if that works. But if it doesn't, just use a lambda:

ranges::sort(v, ranges::less(), [](auto const& elem) { return elem.second.size(); });
Barry
  • 286,269
  • 29
  • 621
  • 977