Search code examples
c++algorithmc++17smart-pointersstdset

How to get the first element in a std::set of pointers, where the pointer points to a specific value?


Say you have a C++ std::set of unique pointers e.g.

auto my_set = std::set<std::unique_ptr<std::string>> 
{ 
    std::make_unique<std::string>("monkey"),
    std::make_unique<std::string>("banana"),
    std::make_unique<std::string>("orange") 
};

Using the std::find_if function, how would you go about finding the first element within this set such that the pointer points to "orange"?

So far I have got:

auto food = "orange";
auto find_orange
   = std::find_if(my_set.begin(), my_set.end(), [&food](const auto& ptr) -> bool {
        return *(*ptr) == food;
    }
);

but this does not compile. Any ideas on what the issue is?

Also in these kinds of functions what exactly is ptr i.e. the parameter in the predicate? Is it a pointer to each element of the container?


Solution

  • The question lacks a proper minimal reproducible example. When we make one MCVC: https://godbolt.org/z/bfYx39

    The problem is coming from lambda return

    return *(*ptr) == food;
    

    as the auto there is std::unique_ptr<std::string>. Therefore you need to just dereference once:

    auto find_orange = std::find_if(my_set.begin(), my_set.end(),
          [&food](const auto& ptr) {
             return *ptr == food;
             //     ^^^^^^^^^^^^
          }
       );
    

    you do not need to double dereferencing there.