Why doesn't this compile?

Very basic, but... why doesn't this compile?

1
2
3
4
5
6
7
map<string,double> dow_price = {
        {"MMM",81.86},
        {"AA",34.69},
        {"MO",54.45}
    };
  
   auto p = find(dow_price.begin(),dow_price.end(),"test");
Because std::find(b, e, k) requires that *b == k be a valid comparison. It's implemented basically like this:
1
2
3
4
5
6
7
template <typename It, typename S>
It std::find(It begin, It end, const S &term){
    for (; begin != end; ++begin)
        if (*begin == term)
            return begin;
    return end;
}


Do this instead, which would be much faster than std::find() anyway:
 
auto p = dow_price.find("test");
Last edited on
What does your compiler tell you?

I get an "algorithm" error, more specifically:

Invalid operands to binary expression ('std::__1::__map_iterator<std::__1::__tree_iterator<std::__1::__value_type<std::__1::basic_string<char>, double>, std::__1::__tree_node<std::__1::__value_type<std::__1::basic_string<char>, double>, void *> *, long> >::value_type' (aka 'pair<const std::__1::basic_string<char>, double>') and 'const char *')

What is the difference between the std::find(b,e,k) and the one you propose, @helios? I thought it was the same function, just written differently?

And, shouldn't (given what you wrote)

auto p = find(dow_price.begin(),dow_price.end(),"MMM");

work, or am I missing something?
Last edited on
No, it shouldn't work, because the type of *dow_price.begin() is std::pair<std::string, double>, not std::string.
Thank you. How would std::find(b,e,k) look for a map, then?
First of all, do not do this! The code I'm about to write takes O(n log n) time. It's even worse than linear search in an unordered array! std::map::find() can find (or not) the element in O(log n) time.

1
2
3
4
5
6
7
8
9
10
struct weird_compare{
    bool operator()(const std::pair<std::string, double> &a, const std::string &b) const{
        return a.first < b;
    }
    bool operator()(const std::string &a, const std::pair<std::string, double> &b) const{
        return a < b.first;
    }
};

auto p = find(dow_price.begin(),dow_price.end(),"MMM", weird_compare());
I haven't tested it, but I believe the above should compile. But seriously, don't.
Thanks!!

what's the difference between std::find(b,e,k) and doing it like this auto p = dow_price.find("test");

Are they completely different functions? I just noticed that <vector> does not have a find() member function, and that you'll have to use std::find(b,e,k)
Yes, they're completely different. std::find() is implemented basically as in the code I wrote in my first post in this thread. std::map::find() uses the std::map's internal data structure (usually some kind of binary search tree) to quickly find the element.

std::vector doesn't have a find() function because std::vector is not designed as a search data structure. If you need to find things quickly (std::find() is not quick) you would not put them in an std::vector.
Topic archived. No new replies allowed.