Dominique Devienne writes:
I would like to support a slightly unusual use-case.
We have a class with a integer member, and a BMI container for
instances of this class.
That member is supposed to be unique, *except* for a special "invalid"
value (-1), which several instances can use.
Right now, we use an ordered_non_unique index, because of the -1's,
but that leaves the door open for other duplicate "valid" values,
which should be forbidden.
So my question is whether one can index this member uniquely, thanks to
a custom comparator, such that the comparator does not violate the
usual strict-weak-ordering requirement of ordered containers?
Steven's answer is, as always, correct, and we can leave it at that. But,
if you want to venture into uncharted lands...
Suppose we use the following:
template
struct punctured_less
{
bool operator()(const T& x,const T& y)const
{
if(x==puncture&&y==puncture)return true;
return x>
>
;
Fist thing to notice is: punctured_less is *not* a strict weak
ordering. For instance, it is not irreflexive as ::operator()(-1,-1)==true.
But if we write:
set s={-3,-2,-1,0,0,1,-1,2,3,-1,4,5,-1,6,7,-1,8,9,9,-1};
for(int x:s)std::cout< Boost.MultiIndex behaves
as if each new -1 to be inserted is less that all other -1s already
in the container.
Insertion sort of works, lookup is more difficult to handle. You can
verify that
s.lower_bound(-1)==s.lower_bound(0)
s.upper_bound(-1)==s.upper_bound(-2)
that is, looking up for -1 behaves as if the -1s are not quite there,
which is (in some sense) consistent with the fact that -1s never
compare false to themselves. Note that
[s.lower_bound(-1),s.upper_bound(-1)) is not a proper range (the
end precedes the beginning). equal_range also behaves oddly:
s.equal_range(-1)==std::make_pair(s.lower_bound(0),s.lower_bound(0)
which is at least a valid range (but not the same as
std::make_pair(s.lower_bound(-1),s.upper_bound(-1)) as guaranteed by the
documentation).
Lookup for values other than -1 behaves perfectly, as it is only when
invoking operator()(-1,-1) that strict weak ordering properties are
violated. If you're able to live in a state of undefined behavior and
cope with the oddities described above, well, you might take advantage of
this.
Joaquín M López Muñoz