1

I found the following program on cplusplus.com.

// set::insert
#include <iostream>
#include <set>

int main (){
    std::set<int> myset;
    std::set<int>::iterator it;
    std::pair<std::set<int>::iterator, bool> ret;

    // set some initial values:
    for (int i = 1; i <= 5; i++) myset.insert(i*10);    // set: 10 20 30 40 50

    ret = myset.insert(20);                // no new element inserted

    if (ret.second == false) it = ret.first;  // "it" now points to element 20

    myset.insert (it, 25);                 // max efficiency inserting
    myset.insert (it, 24);                 // max efficiency inserting
    myset.insert (it, 26);                 // no max efficiency inserting

    int myints[] = {5, 10, 15};            // 10 already in set, not inserted
    myset.insert (myints, myints+3);

    std::cout << "myset contains:";
    for (it = myset.begin(); it != myset.end(); it++)
        std::cout << ' ' << *it;
    std::cout << '\n';

    return 0;
}

The output of this program is:

myset contains: 5 10 15 20 24 25 26 30 40 50

On 16th line, the comment says that the std::set<int>::iterator it now points to the element 20, the second element in the set. But I don't seem to understand why it happen so or how the statement if (ret.second == false) it = ret.first; actually works.

It would be really helpful if someone explains me how this code works. However, it may be kept in mind that I'm new to std::set.

Meraj al Maksud
  • 1,528
  • 2
  • 22
  • 36

2 Answers2

3

single element (1): pair<iterator,bool> insert (const value_type& val);

The single element versions (1) return a pair, with its member pair::first set to an iterator pointing to either the newly inserted element or to the equivalent element already in the set. The pair::second element in the pair is set to true if a new element was inserted or false if an equivalent element already existed.

The above paraphrase from http://www.cplusplus.com/reference/set/set/insert/ clears everything.

for (int i=1; i<=5; ++i) myset.insert(i*10); Here 20 is already inserted.

And again you are trying to insert 20, which is already there, so insert returns the pair containing iterator and false i.e. pair's second term is false.

P.S. If you are using modern C++ standards like (C++11, 14, 17 or 20), then you should refer to https://en.cppreference.com/w/ since it's updated.

Community
  • 1
  • 1
kiner_shah
  • 3,939
  • 7
  • 23
  • 37
  • @JeJo, you are right! But, the OP mentioned C++98 (see his posted code's first line - it's in the comment) that's why I particularly added that function signature! – kiner_shah Jul 06 '19 at 12:12
3

From the cppreference:

Returns a pair consisting of an iterator to the inserted element (or to the element that prevented the insertion) and a bool value set to true if the insertion took place.

Since the set in your example already contains the element 20, the iterator to it is returned.

The reasoning for this is that part of the inserting algorithm is finding a place for this new element. This place is obviously the same as where we would look for it if it were in the container.

So, again, we look where it should be, if it's not there, we put it there. If it is, then we simply return an iterator to this place. This extra operation is then basically free.

Quimby
  • 17,735
  • 4
  • 35
  • 55
  • 1
    Also showing the overload of `std::set::insert` might be helpful: `std::pair insert( value_type&& value );` – JeJo Jul 06 '19 at 12:02