Signature of the predicate in std::lower_bound

P

phdscholar80

I am using the following code:

#include <vector>
#include <algorithm>

class A
{
};

bool comparator( A * b, const char * a )
{
// return appropriate true/false value
}

int main( int argc, char * argv[] )
{
std::vector< A * > vt;
const char * p = "a";

std::lower_bound( vt.begin(), vt.end(), p, comparator );

return 0;
}

Note that the second argument of the comparator function is the same
as 'p', the 'object' that is being provided. Is this a standard
compliant technique? If not, shouldn't the standard allow this? It
comes in useful in a LOT of situations. (Incase you are wondering,
this worked perfectly on Visual Studio 2003 but doesn't work on Visual
Studio 2005 with SP1).
 
V

Victor Bazarov

I am using the following code:

#include <vector>
#include <algorithm>

class A
{
};

bool comparator( A * b, const char * a )
{
// return appropriate true/false value
}

int main( int argc, char * argv[] )
{
std::vector< A * > vt;
const char * p = "a";

std::lower_bound( vt.begin(), vt.end(), p, comparator );

return 0;
}

Note that the second argument of the comparator function is the same
as 'p', the 'object' that is being provided. Is this a standard
compliant technique? If not, shouldn't the standard allow this? It
comes in useful in a LOT of situations. (Incase you are wondering,
this worked perfectly on Visual Studio 2003 but doesn't work on Visual
Studio 2005 with SP1).

I couldn't find any direct set of requirements for the 'Compare' argument
of 'lower_bound' template except that the container "should be partitioned
with respect to 'comp(e, value)'", where 'comp' is your 'comparator'.
Whether this requires the 'comparator' to be callable with 'a' and 'b'
reversed (that's what Visual C++ requires, and that's why it fails) is
open to interpretation.

V
 
R

Richard Herring

Victor Bazarov said:
I am using the following code:

#include <vector>
#include <algorithm>

class A
{
};

bool comparator( A * b, const char * a )
{
// return appropriate true/false value
}

int main( int argc, char * argv[] )
{
std::vector< A * > vt;
const char * p = "a";

std::lower_bound( vt.begin(), vt.end(), p, comparator );

return 0;
}

Note that the second argument of the comparator function is the same
as 'p', the 'object' that is being provided. Is this a standard
compliant technique? If not, shouldn't the standard allow this? It
comes in useful in a LOT of situations. (Incase you are wondering,
this worked perfectly on Visual Studio 2003 but doesn't work on Visual
Studio 2005 with SP1).

I couldn't find any direct set of requirements for the 'Compare' argument
of 'lower_bound' template except that the container "should be partitioned
with respect to 'comp(e, value)'", where 'comp' is your 'comparator'.
Whether this requires the 'comparator' to be callable with 'a' and 'b'
reversed (that's what Visual C++ requires, and that's why it fails) is
open to interpretation.
I've tripped over this one as well.

IIRC the reason for VS2005 behaving this way is that (in debug mode) the
library does some run-time tests that the comparison really is a strict
weak ordering, by verifying that comp(a, b) and comp(b, a) are not both
true.
 
P

phdscholar80

In message <[email protected]>, Victor Bazarov


I am using the following code:
#include <vector>
#include <algorithm>
class A
{
};
bool comparator( A * b, const char * a )
{
// return appropriate true/false value
}
int main( int argc, char * argv[] )
{
std::vector< A * > vt;
const char * p = "a";
std::lower_bound( vt.begin(), vt.end(), p, comparator );
return 0;
}
Note that the second argument of the comparator function is the same
as 'p', the 'object' that is being provided. Is this a standard
compliant technique? If not, shouldn't the standard allow this? It
comes in useful in a LOT of situations. (Incase you are wondering,
this worked perfectly on Visual Studio 2003 but doesn't work on Visual
Studio 2005 with SP1).
I couldn't find any direct set of requirements for the 'Compare' argument
of 'lower_bound' template except that the container "should be partitioned
with respect to 'comp(e, value)'", where 'comp' is your 'comparator'.
Whether this requires the 'comparator' to be callable with 'a' and 'b'
reversed (that's what Visual C++ requires, and that's why it fails) is
open to interpretation.

I've tripped over this one as well.

IIRC the reason for VS2005 behaving this way is that (in debug mode) the
library does some run-time tests that the comparison really is a strict
weak ordering, by verifying that comp(a, b) and comp(b, a) are not both
true.

Just discovered a way around so posting it for everyone's benefit. I
don't think this is something new, people probably already knew this.
I ought to have thought of this solution earlier. Anyways, the
solution is to create a class:

class Comparator
{
public:

bool operator( const char * a, A * b ) { // return a < b }
bool operator( A * a, const char * b ) { // return a < b }
};

and then

Comparator comp;
std::lower_bound( vt.begin(), vt.end(), "kdkdj", comp );

and TADA. Hope this helps.
 
V

Victor Bazarov

[..]
Just discovered a way around so posting it for everyone's benefit. I
don't think this is something new, people probably already knew this.
I ought to have thought of this solution earlier. Anyways, the
solution is to create a class:

class Comparator
{
public:

bool operator( const char * a, A * b ) { // return a < b }
bool operator( A * a, const char * b ) { // return a < b }

Just to note that this is not compilable code, it's some kind of
pseudo-code, I am guessing. Should probably be

bool operator()(const char*, A*) const; // ..
bool operator()(A*, const char*) const; // ..
};

and then

Comparator comp;
std::lower_bound( vt.begin(), vt.end(), "kdkdj", comp );

and TADA. Hope this helps.

Good idea, BTW.

V
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,743
Messages
2,569,478
Members
44,898
Latest member
BlairH7607

Latest Threads

Top