Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using lower_bound, upper_bound, and binary_search to find the object with an equal member field

Tags:

c++

search

stl

I have a struct that looks like this,

struct Foo {
    int a;
};

I have a vector of these structs that look like this,

vector<Foo> foos;

All of the Foos are sorted by the integer a in ascending order using the STL sort() function. Now I want to get the Foo object that has the member field a less than or equal to a given number, like the STL lower_bound() function. The problem is that the STL lower_bound function declaration looks like this:

template <class ForwardIterator, class T, class Compare>
  ForwardIterator lower_bound ( ForwardIterator first, ForwardIterator last,
                                const T& value, Compare comp );

So while I want to do something like,

lower_bound(foos.begin(), foos.end(), 5, custom_comp);

I can't because the int I'm looking for (5 in this case) is not of the type Foo. I'm having this issue with lower_bound(), upper_bound(), and binary_search(). custom_comp only defines the ordering and doesn't define that an object with a = 5 actually equals the int 5.

Is there any elegant way of doing this with STL?

Edit:

I realized my example doesn't completely represent my problem. What I actually have is that Foo contains two ints, a and b. When I call lower_bound, I don't have access to b (because I don't care about it). Now the issue with billz answer is that I'd have to define a constructor that takes only a as a parameter, which isn't very elegant in my opinion (because b is left undefined or abitrary, and this constructor can be used anywhere in the code). But if this is the only option, I'll take it.

like image 469
gsingh2011 Avatar asked Nov 03 '22 11:11

gsingh2011


1 Answers

You could provide a constructor to your struct Foo

struct Foo {
  Foo(int x):a(x){
  }
    int a;
};

you can now call:

std::lower_bound(foos.begin(), foos.end(), 5, custom_comp);

or

std::lower_bound(foos.begin(), foos.end(), Foo(5), custom_comp);

or

Foo f(5);
std::lower_bound(foos.begin(), foos.end(), f, custom_comp);

The suggested way is:

struct Foo {
  explicit Foo(int x):a(x){
  }
    int a;
};

std::lower_bound(foos.begin(), foos.end(), Foo(5), custom_comp);
like image 194
billz Avatar answered Nov 12 '22 19:11

billz