tags:

views:

571

answers:

3

I want to find the first item in a sorted vector that has a field less than some value x.
I need to supply a compare function that compares 'x' with the internal value in MyClass but I can't work out the function declaration.
Can't I simply overload '<' but how do I do this when the args are '&MyClass' and 'float' ?

 float x;
 std::vector< MyClass >::iterator last = std::upper_bound(myClass.begin(),myClass.end(),x);
A: 

I think what you need is std::bind2nd(std::less<MyClass>(), x). But, of course, the operator< must be defined for MyClass.

Edit: oh and I think you will need a constructor for MyClass that accepts only a float so that it can be implicitly converted. However, there might be a better way to do this.

Borbus
+4  A: 

What function did you pass to the sort algorithm? You should be able to use the same one for upper_bound and lower_bound.

The easiest way to make the comparison work is to create a dummy object with the key field set to your search value. Then the comparison will always be between like objects.

Edit: If for some reason you can't obtain a dummy object with the proper comparison value, then you can create a comparison functor. The functor can provide three overloads for operator() :

struct MyClassLessThan
{
    bool operator() (const & MyClass left, const & MyClass right)
    {
        return left.key < right.key;
    }
    bool operator() (const & MyClass left, float right)
    {
        return left.key < right;
    }
    bool operator() (float left, const & MyClass right)
    {
        return left < right.key;
    }
};

As you can see, that's the long way to go about it.

Mark Ransom
That was the problem, the sort function takes two const refs to MyClass objects. The search function must take a MyClass and a float. Same problem for using bind2nd() the
Martin Beckett
operator() to compare things - now why didn't I think of that !!!The more I use STL the more I love python. thank you
Martin Beckett
+1  A: 

You can further improve Mark's solution by creating a static instance of MyClassLessThan in MyClass

class CMyClass 
{
   static struct _CompareFloatField
   {
      bool operator() (const MyClass & left, float right) //...
      // ...
   } CompareFloatField;
};

This way you can call lower_bound in the following way:

std::lower_bound(coll.begin(), coll.end(), target, CMyClass::CompareFloatField);

This makes it a bit more readable

Ghostrider
I would still need a dummy object and an operator() for each member - but your's is clearer in reading the intent - thanks
Martin Beckett