0

I have this question:

I have a std::map of strings to integers representing list of fruits:

map<string, int> fruits{
    {"Apple", 5}, {"Grapefruit", 7}, {"Cherry", 10}, {"Grapes", 16}
};


for (const auto& p : fruits)
    cout << p.first << " " << p.second << endl;
cout << endl << endl;


auto it = fruits.begin();
++++it;

using type = std::pair<class std::basic_string<char, struct std::char_traits<char>, class std::allocator<char> > const, int>;

auto it2 = std::lower_bound(fruits.cbegin(), fruits.cend(), type{"Cherry", 10});
//  auto it3 = std::lower_bound(fruits.cbegin(), fruits.cend(), pair<string, int>{ "Cherry", 10 });
auto it4 = std::lower_bound(fruits.cbegin(), fruits.cend(), pair<const string, int>{ "Cherry", 10 });

for (auto beg = fruits.cbegin(); beg != it2; ++beg)
    cout << beg->first << " " << beg->second << endl;

cout << typeid(*it).name() << endl;

So my problem was How to pass the third parameter to std::lower_bound explicitly?

  • Because after getting help from typeid I've noticed that the pair's first is const is this because the keys are constants?

  • Also what happen if I pass the value for a given key that is not matching the key in the container. e.g: the element with key "Cherry" has a value 10 so why lower_bound works correctly if I pass to it invalid value with the key like pair{"Cherry", 345}?

  • Is the value of the pair passed to lower_bound arbitrary?

Itachi Uchiwa
  • 3,044
  • 12
  • 26
  • 1
    Do you really want to compare both key and value or are you only interested in the key? If its the latter, std::map has a lower_bound member(https://en.cppreference.com/w/cpp/container/map/lower_bound) – Philipp Lenk Oct 06 '19 at 23:32
  • @PhilippLenk: Yes. I get it. is it correct my guess about `const`? Thank you – Itachi Uchiwa Oct 06 '19 at 23:40
  • 1
    It is const because modifying the key's value via iterators or such could potentially break the data structure(as the nodes would have to be reordered). Safely modifying the keys could be done via C++17's extract(https://en.cppreference.com/w/cpp/container/map/extract), which hands you a node removed from the map – Philipp Lenk Oct 06 '19 at 23:42
  • @PhilippLenk: Thank you – Itachi Uchiwa Oct 06 '19 at 23:44

1 Answers1

7

Don't do that. std::map has its own member function lower_bound so that you don't need a comparison function, and it's more efficient too.

An iterator to map has the first part const because you can't change it. The data types and algorithms used rely on the key value remaining the same over the life of the map.

Mark Ransom
  • 299,747
  • 42
  • 398
  • 622
  • Ah ok. I really tried that. Becuase in my book it is said always use the members of the associative containers (algorithms ) rather than using the generic ones. But add the first part of the questions about constness. Thank you. – Itachi Uchiwa Oct 06 '19 at 23:36
  • Ok Now Thank you. – Itachi Uchiwa Oct 06 '19 at 23:44