Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Get projected value from std::ranges algorithms

I am using algorithms from std::ranges (max and max_element) with a projection.
Is it possible for the result to also be the projected value? Currently I have to call the projection function again on the returned value.

Example:
Here I want the size of the longest string, but the algorithms return only the string or an iterator to it.

int main()
{
    const std::vector<std::string> vec = {
        "foo",
        "hello",
        "this is a long string",
        "bar"
    };

    //r1 is a string. r2 is an iterator
    const auto r1 = std::ranges::max(vec, {}, &std::string::size);
    const auto r2 = std::ranges::max_element(vec, {}, &std::string::size);
    
    //I have to call size() again
    std::cout << r1 << '\n' << *r2 << '\n';
    std::cout << r1.size() << '\n' << r2->size() << std::endl;
}

Compiler Explorer

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

You’re using an algorithm (max/max_element) on the original range, which can’t do anything but give you an element/iterator into the range.

If you want just the projected values, do the projection (via a views::transform) to get the lengths first, and then find the maximum of that

auto const lens = std::views::transform(vec, &std::string::size);

const auto r1 = std::ranges::max(lens);
const auto r2 = std::ranges::max_element(lens);

std::cout << r1 << '\n' << *r2 << '\n';  // prints 21 21

Here’s a demo.


As mentioned in this answer, taking the address of std::string::size is not permitted, so you should use a lambda instead. In general though, taking a projection based on a member function works just fine, so long as it’s not a std function.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading