Re: std::unique specification vs. reality
On Sun, 04 Jun 2006 18:33:33 -0400, Bo Persson wrote:
[...]
There's also situations with user defined classes that have extra
state
beyond whatever defines "equality":
[...]
Sure, but that is not involved in std::unique. It always keeps the
first element.
Ok, how about this example:
struct foo {
mutable int times_read;
int state;
explicit foo()
: state(0)
, times_read(0)
{}
bool
operator==(foo const& o) const
{
++times_read;
return state == o.state;
}
};
std::vector<foo> blah(10);
blah.remove(
blah.end(),
std::unique(blah.begin(), blah.end()));
assert(blah.size() == 1);
assert(blah[0].times_read == 1); // fails in real world implementations
The standard says we're going to get last - first applications of
predicate, and each element at any iterator i is considered non-unique
if operator==(*i, *(i - 1)); Presumably this implies that blah[0]
is only passed to operator== once, so its times_read must be 1.
But in the two implementations I looked at, blah[0].times_read would
instead be 9.
Now, obviously this is a bit pedantic, since you probably won't write
an operator== like this and depend on the behavior. It does matter if
predicate is not an equivalence relation, but it sounds from your post
like the next standard will require that it is.
By the way, I also noticed in the SGI STL documentation an explicit
note that the BinaryPredicate to std::unique did not need to be a test
for equality:
BinaryPredicate is not required to be an equivalence relation.
You should be cautious, though, about using unique with a Binary
Predicate that is not an equivalence relation: you could easily get
unexpected results.
(http://www.sgi.com/tech/stl/unique.html)
Hopefully changing the standard doesn't break any code relying on
the above. :-)
--
Jordan DeLong
fracture@allusion.net
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]