0

In C++ prime 5 Ed chapter 11. Associative containers. "Table 11.7. Operations to Find Elements in an Associative Container":

It is said: "c.equal_range(k) returns a pair of iterators denoting the elements with key k. if k is not present, both members are c.end()."

set<int> si{ 5, 7, 23, 16, 81, 24, 10};
auto it = si.equal_range(13);
cout << *it.first << " " << *it.second << endl; // 16 16
  • But as you can see above 13 was not found but it returns a pair of iterators for elements16, 16?!
Itachi Uchiwa
  • 3,044
  • 12
  • 26
  • 1
    See also https://stackoverflow.com/a/12159150/596781. Note that `equal_range` does not return the end iterator if the key is not found, but rather it returns a lower_bound/upper_bound pair (which is equal if the element is not found). – Kerrek SB Oct 07 '19 at 00:45
  • @KerrekSB: Is it logical that the `equal_range` returns the `first` as `16` whereas the value requested is `13`. I think this is incorrect result ; It should return `off-end` rather than returning incorrect result. – Itachi Uchiwa Oct 07 '19 at 12:31
  • 1
    Yes, because the result is a _range_, and the range is _empty_ if nothing is found. (The right question to ask the range is not where it starts, but what's in it.) Additionally, the range has the value of telling you where the element _would_ be if it existed, which allows you, say, to insert it cheaply. – Kerrek SB Oct 07 '19 at 17:31

1 Answers1

1

Running this program, it works as intended: It returns the end iterators.

int main (int argc, char** argv) {
    std::set<int> si{ 5, 7, 23, 16, 81, 24, 10};
    auto it = si.equal_range(99);

    if(it.first == std::end(si)) {
        std::cout << "Element not found." << std::endl;
    }
    else {
        std::cout << *it.first << ", " << *it.second << std::endl;
    }

    return 0;
}

But, if I were to check for 13, I'd get back 16, 16.

According to cppreference.com

Returns a range containing all elements with the given key in the container. The range is defined by two iterators, one pointing to the first element that is not less than key and another pointing to the first element greater than key. Alternatively, the first iterator may be obtained with lower_bound(), and the second with upper_bound().

16 just happens to be the first element that is not less than and also greater than 13 in your example.

Acorn
  • 1,147
  • 12
  • 27
  • 1
    Yes exactly and is also mentioned on page 440 of the book you are referring, also note that elements in a `set` are sorted(using strict weak ordering) if you get confused on 16-16 – Abdul kareem Oct 07 '19 at 00:53
  • The link of CppReference seems to be broken. Thank you anyway. – Itachi Uchiwa Oct 07 '19 at 12:22
  • @ItachiUchiwa weird, somehow I put a comma at the end of the URL. Should work now! – Acorn Oct 09 '19 at 03:24