While trying to solve a problem I started thinking about this - given a user-defined class
and 2 comparators
for it, lets say we have 2 sets std::set<user_class,comparator_inc>
and std::set<user_class,comparator_dec>
where the comparators
sort by increasing and decreasing value on a value in the user_class
(a simple int
perhaps). Here's my code:
#include <iostream>
#include <set>
using std::cout;
using std::endl;
using std::set;
struct A
{
int val;
};
struct c_inc
{
bool operator()(const A& first,const A& second) const
{
return first.val > second.val;
}
};
struct c_dec
{
bool operator()(const A& first,const A& second) const
{
return first.val < second.val;
}
};
int main()
{
set<A,c_inc> s1;
set<A,c_dec> s2;
auto x = s1.insert({1});
cout << x.first->val << endl;
x = s2.insert({1});
x = s2.insert({0});
cout << x.first->val << endl;
}
My question is: Is it defined behavior to re-assign x
to the output of insert
into a set
with same Key
but different comparator? Is there a problem with this kind of use? Is it defined in the standard somewhere what it should be or is it implementation dependent?
Since the code compiles I think that the return
type of insert
in both cases is the same - is this assumption correct?
I think it's implementation dependent.
Conceptually the return type of s1.insert
and s2.insert
are different; especially they have different iterator types, i.e. std::set<A,c_inc>::iterator
and std::set<A,c_dec>::iterator
. And how the std::set::iterator
's type is defined is implementation-defined.
[set.overview]/2
using iterator = implementation-defined; // see [container.requirements] using const_iterator = implementation-defined; // see [container.requirements]
Technically speaking, you shouldn't rely on this.
Since the code compiles I think that the return type of insert in both cases is the same - is this assumption correct?
No, it is not. Imagine this simple example:
template<class T>
struct set {
struct iterator { /*...*/ };
};
In this case set<int>::iterator
is definitely different from set<double>::iterator
.
The implementation is free to implement the iterator type as a free class though (since the iterator does not depend on the comparator), which seems to be the case in the major implementations, and is what's allowing your example.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With