HiveBrain v1.2.0
Get Started
← Back to all entries
patterncppMinor

Using set for unordered, unique list of elements

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
uniqueunorderedelementsforusinglistset

Problem

In C++11 we have the option of using std::unordered_set if we require a list of elements that have no duplicates but order is not important.

In C++03 we don't have this options, although we can use the std::set to achieve something similar. Let's consider the following code:

std::set> unorderedSet;
unorderedSet.insert(some_element);
unorderedSet.insert(other_element);
unorderedSet.insert(some_element);

//... more stuff with the set


This will, basically produce a set that will store the elements in the order they were inserted while preventing duplicates. Note that ElementType simply can't have less than or greater than operator. It doesn't make sense, semantically speaking.

Anyway, since I am using std::NotEqualTo instead of a LessThan functor, as it is requested by the set, I am not feeling very comfortable with this code. I do know that set is using something such as

if first element < second element
    //insert accordingly 
else if second element < first element
    //insert accordingly
else
   //they are equal


but in the same time, theoretically, my code will be failing if the checks were more strict such as

if first element < second element AND !(second element < first element)
//...


My questions are:

  • There are any potentially problems that could arise from using this construct?



  • What other alternatives I have to achieve the same thing in a more readable form? I do not plan to write my own unordered set just for this scenario and can't really use any external libraries. Only standard library available in C++03.



Edit: I am unable to make use of "less than" operator between my elements. I can decide if they are equal or not but I can't say which one is smaller than other. With the default set functor the code won't even compile as "operator<" is not found. This is why I wanted to model the functor with equal operator in the first case.

I am also aware that it is not valid, however, the code will produce the de

Solution

My questions are:

There are any potentially problems that could arise from using this construct?

Its not valid.

The code will not work as expected as the std::set requires the comparator type to generate a strict weak ordering between elements.

What other alternatives I have to achieve the same thing in a more readable form? I do not plan to write my own unordered set just for this scenario and can't really use any external libraries. Only standard library available in C++03.

You can use std::set as an unordered container as is. If you have an unordered container it does not matter to you what order the elements are in. If they just happen to be ordered does that matter?

The reason for using std::unordred_set is that it provides faster access to the elements. You give up an ordered property to get better performance.

Container:           Insert     find
std::set             O(ln(n))  O(ln(n))
std::unordered_Set   O(1)      O(1)

Code Snippets

Container:           Insert     find
std::set             O(ln(n))  O(ln(n))
std::unordered_Set   O(1)      O(1)

Context

StackExchange Code Review Q#32475, answer score: 6

Revisions (0)

No revisions yet.