|
Boost : |
From: Douglas Gregor (gregod_at_[hidden])
Date: 2002-10-16 21:51:58
On Wednesday 16 October 2002 10:17 pm, Kevin S. Van Horn wrote:
> Douglas Gregor writes:
> > there are yet more subtle errors (this one from the Comeau standard
> > library, libcomo) that aren't caught by the concept checks library:
> >
> > template <class _InputIter, class _Predicate>
> > inline _InputIter find_if(_InputIter __first, _InputIter __last,
> > _Predicate __pred,
> > input_iterator_tag)
> > {
> > while (__first != __last && !__pred(*__first))
> > ++__first;
> > return __first;
> > }
>
> OK, I'm stumped. What's wrong with the above code? (The GNU libstdc++
> code is identical.)
InputIterators are required to be EqualityComparable, which states that the
result of '__first != __last' should be convertible to bool. Similarly, a
(unary) Predicate is required to be a function object whose result_type is
convertible to bool. There is no requirement that the expression
__first != __last && !__pred(*__first)
be valid, so we _could_ have the pathological case where:
__first != __last returns an object of type 'Foo' (Foos are convertible to
bool)
__pred(*__first) returns an object of type 'Bar' (Bars are convertible to
bool)
operator&&(Foo, Bar) is defined with different semantics than operator&&(bool,
bool)
The fix is just a pair of static_cast<bool>'s, and it's doubtful that this
_particular_ error would ever occur, but still it's an error that is
non-obvious and is not found by the Boost Concept Check library (one would
need to poison operator&&(boolean_archetype, boolean_archetype to find it).
Doug
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk