0

In this so question about sorting only some fields in a std::vector of struct, this interesting answer was provided:

std::vector<SimpleStruct> vs = {{1, 10, 11}, {5, 100, 111}, {3, 1000, 1111}};
std::ranges::sort(vs | std::views::transform(&SimpleStruct::a));
// vs now becomes {1, 10, 11}, {3, 100, 111}, {5, 1000, 1111}

The goal, I get, is to emulate a view that would act as a std::vector of only the field a.

Yet, I don't get how std::views:transform can use a pointer to data member as a transformation function. As far as I understand the documentation it should be passed a callable object.

Why and how is it working as expected (I probably missed an important detail in cppreference).

5
  • 4
    Pointers to data members are callable (you can do std::invoke(object, &Class::member) and get object.member back). It's a weird, but useful quirk in the language. Side note: this could also be spelled with a projection - std::ranges::sort(vs, {}, &SimpleStruct::a) Commented Jun 19, 2024 at 8:09
  • I totally overlooked this detail. Thanks a lot (I tried obj.*p() which was rejected but not std::invoke). Thanks again. The dup is OK. Commented Jun 19, 2024 at 8:14
  • 1
    Yeah, C++ standard since at least C++11 had defined Callable requirements with an imaginary function INVOKE that can take a function and its arguments and call that function. And this imaginary INVOKE was defined to also be able to accept pointers to data members. Since C++17 we have a real implementation of INVOKE - std::invoke. Commented Jun 19, 2024 at 8:19
  • 4
    @Yksisarvinen The projection is only used for the comparison in ranges::sort; the algorithm still swaps the complete elements. But this particular case really only wants to swap the members. For this reason, the variant with the projection cannot be used. Commented Jun 19, 2024 at 9:32
  • @j6t Ah, I see, you're right of course. Commented Jun 19, 2024 at 10:06

0

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.