From: James Kanze on
Otis Bricker wrote:
> I'm trying to figure out is the following technique is valid.

> Given
> std::vector<DataItem> cache;

> which is sorted by the ID_ field of each DataItem.

> And this Predicate class:

> class IdLessThan: public std::binary_function<long, DataItem, bool>
> {
> public:
> bool operator()
> ( long lhs, const DataItem& rhs)const{return lhs <
> rhs.ID_;};
> };

> Is the following valid?

> Vector<DataItem>::iterator it =
> std::upper_bound(cache.begin(),cache.end(),ID, IdLessThan());

No. Given this call, IdLessThan must be callable with a first
argument of type DataItem, and a second of type long (and the
reverse).

> I ask because the compiler I am using is unable to compile the debug
> build of this. It seems to be trying to test the predicate by calling:

> IdLessThan::operator()(const DataItem& lhs,long rhs);

> Is this version required or is it just a case of a debug version
> requiring it for 'testing', which I believe can be disabled?

It's required. It is, in fact, the only version required.

> And would it be a good idea to include the extra form to allow the
> testing by the debug build?

Generally, if you can't build the debug version, it's best to
suppose that the production version won't work correctly anyway.
(In this case, I'd be surprised if you could build any version.)

--
James Kanze (Gabi Software) email: james.kanze(a)gmail.com
Conseils en informatique orient�e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S�mard, 78210 St.-Cyr-l'�cole, France, +33 (0)1 30 23 00 34



--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Otis Bricker on
"Daniel T." <daniel_t(a)earthlink.net> wrote in
news:daniel_t-242458.00025327012007(a)news.west.earthlink.net:

> In article <Xns98C4680FC6F84obrickermydejanewsco(a)216.196.97.136>,
> Otis Bricker <obricker(a)my-dejanews.com> wrote:
>
>> I'm trying to figure out is the following technique is valid.
>>
>> Given
>> std::vector<DataItem> cache;
>>
>> which is sorted by the ID_ field of each DataItem.
>>
>> And this Predicate class:
>>
>> class IdLessThan: public std::binary_function<long, DataItem, bool>
>> {
>> public:
>> bool operator()
>> ( long lhs, const DataItem& rhs)const{return lhs <
>> rhs.ID_;};
>> };
>>
>> Is the following valid?
>>
>> Vector<DataItem>::iterator it =
>> std::upper_bound(cache.begin(),cache.end(),ID,
>> IdLessThan());
>
> The following should compile fine:
>
> #include <algorithm>
> #include <functional>
> #include <vector>
>
> using namespace std;
>
> struct DataItem
> {
> long ID_;
> };
>
> class IdLessThan: public binary_function<long, DataItem, bool>
> {
> public:
> bool operator()( long lhs, const DataItem& rhs ) const {
> return lhs < rhs.ID_;
> }
> };
>
> int main()
> {
> long ID;
> vector<DataItem> cache;
> vector<DataItem>::iterator it =
> upper_bound( cache.begin(), cache.end(), ID, IdLessThan() );
> }
>

Thank you for doing the work I should have. Why I didn't just post a
'working' sample is beyond me.

>> I ask because the compiler I am using is unable to compile the debug
>> build of this. It seems to be trying to test the predicate by
>> calling:
>>
>> IdLessThan::operator()(const DataItem& lhs,long rhs);
>>
>> Is this version required or is it just a case of a debug version
>> requiring it for 'testing', which I believe can be disabled?
>>
>> And would it be a good idea to include the extra form to allow the
>> testing by the debug build?
>
> Adding the extra op() is better than not being able to compile in
> debug! Maybe you should get a newer compiler instead (if you can.)
>

Actually, this happened while we are trying to update our compiler to a
newer version that is supposed to be more Standard complient.

It seems that the debug STL code is trying to be helpful and tries to
test that Pred(x,y)!=Pred(y,x).

if (!_Pred(_Left, _Right))
return (false);
else if (_Pred(_Right, _Left))
_DEBUG_ERROR2("invalid operator<", _Where, _Line);
return (true);

AS many have suggested, it makes sense to just include both versions.
And perhaps a version for operator()(const DataItem&,const DataItem&) so
that it could even check that the range is ordered, if that is
implemented for debug.

But I am a bit surprised that some have said that the version
operator()(const DataItem&,long) is the one that is needed, though I
might have misunderstood the comments. The couple of compilers I had
tried all worked with the operator()(long,const DataItem&). I tried
something else and found that for lower_bound my current compiler does
seem to want (const DI&,long). I can understand this.

If the test was simply std::less<DataItem>, I would have expected the
upper_bound to be calling less::operator()(myvalue,testValue) and the
first point that passed( or the end of range) would be the result. With
lower_bound and less, I would expect it to be testing
not(less::operator()(testValue,myValue)) and terminating the same way.

Of course, I imagine that it could be implemented in other ways. Or I
could just have my head on backwards today.

Thanks again to all for the help thinking about this.

Otis Bricker


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Daniel T. on
"James Kanze" <james.kanze(a)gmail.com> wrote:

> Otis Bricker wrote:
> > I'm trying to figure out is the following technique is valid.
>
> > Given
> > std::vector<DataItem> cache;
>
> > which is sorted by the ID_ field of each DataItem.
>
> > And this Predicate class:
>
> > class IdLessThan: public std::binary_function<long, DataItem, bool>
> > {
> > public:
> > bool operator()
> > ( long lhs, const DataItem& rhs)const{return lhs <
> > rhs.ID_;};
> > };
>
> > Is the following valid?
>
> > Vector<DataItem>::iterator it =
> > std::upper_bound(cache.begin(),cache.end(),ID, IdLessThan());
>
> No. Given this call, IdLessThan must be callable with a first
> argument of type DataItem, and a second of type long (and the
> reverse).

Several people have said this now, but the OPs code works fine in gcc
and at http://www.comeaucomputing.com/tryitout/.

Also, Dikumware's and SGI's documentation say that upper_bound only uses
pred(x, y) where x is the 3rd argument passed in and y is the elements
in the container.

What am I missing?

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Otis Bricker on
"Greg Herlihy" <greghe(a)pacbell.net> wrote in
news:1169873749.305383.305950(a)v45g2000cwv.googlegroups.com:

>
>
> On Jan 26, 3:14 pm, Otis Bricker <obric...(a)my-dejanews.com> wrote:
>> I'm trying to figure out is the following technique is valid.
>>
>> Given
>> std::vector<DataItem> cache;
>>
>> which is sorted by the ID_ field of each DataItem.
>>
>> And this Predicate class:
>>
>> class IdLessThan: public std::binary_function<long, DataItem, bool>
>> {
>> public:
>> bool operator()
>> ( long lhs, const DataItem& rhs)const{return lhs <
>> rhs.ID_;};
>>
>> };
>> Is the following valid?
>>
>> Vector<DataItem>::iterator it =
>> std::upper_bound(cache.begin(),cache.end(),ID, IdLessThan());
>
> No, the first parameter of the IdLessThan predicate function object
> should be the dereferenced iterator value, while the second parameter
> should be the comparison value (see �25/8). In other words, the
> current declaration has the parameters in the reverse of their expected
> order.
>

I guess it would help to have a copy of the standard to review. The draft
version I usually reference online says:

"Returns: The furthermost iterator i in the range [first,last) such that
any iterator j in the range of [first,i) the following corresponding
conditions hold: !(value<*j) or comp(value,*j)==false"

The this param order, (long,const DataItem&) seems more in line with a
standard binary predicate like std::less.

And since the release build does not compile if I include only the (const
dataItem&,long) version, does that mean the compiler is non-conforming?

Guess I need to pop for a copy of the standard.

Thanks.

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Carl Barron on
Otis Bricker <obricker(a)my-dejanews.com> wrote:

> But I am a bit surprised that some have said that the version
> operator()(const DataItem&,long) is the one that is needed, though I
> might have misunderstood the comments. The couple of compilers I had
> tried all worked with the operator()(long,const DataItem&). I tried
> something else and found that for lower_bound my current compiler does
> seem to want (const DI&,long). I can understand this.
>
> If the test was simply std::less<DataItem>, I would have expected the
> upper_bound to be calling less::operator()(myvalue,testValue) and the
> first point that passed( or the end of range) would be the result. With
> lower_bound and less, I would expect it to be testing
> not(less::operator()(testValue,myValue)) and terminating the same way.
>
> Of course, I imagine that it could be implemented in other ways. Or I
> could just have my head on backwards today.
>
> Thanks again to all for the help thinking about this.
>
> Otis Bricker

Well upper_bound and lower_bound assume a sorted sequence and a weak
ordering, so that the other relops can be emulated with just the code
for less than. [a user specifiec binary predicate, or operator < ()]
That said there is using normal operators

x > y iff y < x
x <= y iff !(y<x)
x >= y iff !(x < y)
x == y iff !(x<y) && !(y<x)
x != y iff x < y && y < x

note some swaps of the arguments. Safer to provide them all so changing
a compiler again does not provide a problem. Further it makes the
predicate more reusable, and easier to maintain/




--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

First  |  Prev  |  Next  |  Last
Pages: 1 2 3 4
Prev: Exception alternatives
Next: class template syntax, maybe?