15

Is there a simple way to detect when a set insert does not occur because the item being inserted already exists in the set? For example, I'd like to display a message to the user that shows the insert failure so that they can find and remove the duplicates in their data more easily. Here's some pseudo code to demonstrate what I'd like to do:

try
{
   items.insert(item)
}

catch insert_failed_item_already_in_set
{
   // show user the failed item
}
jww
  • 97,681
  • 90
  • 411
  • 885
01100110
  • 2,294
  • 3
  • 23
  • 32
  • http://www.cplusplus.com/reference/stl/set/insert/ – UmNyobe Mar 06 '12 at 15:10
  • 2
    Something wrong with your C++ standard library reference? You don't even look up the return type of functions you use? – Lightness Races in Orbit Mar 06 '12 at 15:13
  • Sorry for the question. I've not used sets much. I know the data structure well, just not how C++ detected insertion failure. I'll not ask these questions here any longer. Thanks to all who took the time to answer. – 01100110 Mar 06 '12 at 15:41

8 Answers8

25

A signature for set::insert is:

pair<iterator,bool> insert ( const value_type& x );

So, your code would look like:

if( !items.insert(item).second )
{   
    show user the failed item
}
Robᵩ
  • 163,533
  • 20
  • 239
  • 308
14

There is this insert signature in std::set

pair<iterator,bool> insert ( const value_type& x );

Test the second of the returned pair, should be set to true if inserted successfully.

Nim
  • 33,299
  • 2
  • 62
  • 101
6

As set insert return pair you can check the state of second element of pair using get<1> which is the Boolean , if your insert is done or not .

if (get<1>(set.insert(x)) == false){
 //Your error log.
}
Parth
  • 93
  • 1
  • 5
4

from cplusplus:

referring to insert(const T& value)

The first version returns a pair, with its member pair::first set to an iterator pointing to either the newly inserted element or to the element that already had its same value in the set. The pair::second element in the pair is set to true if a new element was inserted or false if an element with the same value existed.

andrea.marangoni
  • 1,499
  • 8
  • 22
4

STL set<>.insert(elem) returns pair<iterator,bool> where the second value in the pair is true if the element was successfully inserted, false otherwise.

malenkiy_scot
  • 16,415
  • 6
  • 64
  • 87
2

An insert operation on a set returns a pair, with its member first set to an iterator pointing to either the newly inserted element or to the equivalent element already in the set. The second element in the pair is set to true if a new element was inserted or false if an equivalent element already existed. So, you can use the second element to determine whether it was added.

For example:

#include <iostream>
#include <set>
using namespace std;
int main ()
{
 std::set<int> myset;
 std::set<int>::iterator it;
 std::pair<std::set<int>::iterator,bool> ret;


 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)
     cout<<"Element already present";

}
Toby Speight
  • 27,591
  • 48
  • 66
  • 103
Prashant Shubham
  • 456
  • 8
  • 20
1

It's easy enough to check if an item is already in a set. If that is the only thing you're looking for there is no need for the try/catch.

if (items.find(item) == items.end())
{
    // Item was not in the set, so put it in the set
    items.insert(item)
}
else
{
    // Item was already in the set
}

Or you can check insert's return value, which is a pair in which is second half of the pair is whether or not the insertion was successful:

if (!items.insert(item).second)
{
    // Item was already in the set
}

Of the two methods, the second method is more compact, and more efficient, as the first method requires two lookups, one during .find, and another during .insert.

Nic Foster
  • 2,864
  • 1
  • 27
  • 45
0

Because set containers do not allow for duplicate values, the insertion operation checks for each element inserted whether another element exists already in the container with the same value, if so, the element is not inserted and -if the function returns a value- an iterator to it is returned.

you can find an example here: http://www.cplusplus.com/reference/stl/set/insert/