using std::find

B

brekehan

If I have a class
MyClass
{
...bunch o data and methods
int x;
};

and a stl container of MyClass objects

Is there a way to use std::find to get all the elements whose member x
is of om value?

All the example on the net are of a collection of some built in type
for simplicity, but do not show how to use a member of your own type
as the value being sought.
 
V

Victor Bazarov

brekehan said:
If I have a class
MyClass
{
...bunch o data and methods
int x;
};

and a stl container of MyClass objects

Is there a way to use std::find to get all the elements whose member x
is of om value?

"om" value? What's "om" value? Sorry, English is not my mother
tongue.
All the example on the net are of a collection of some built in type
for simplicity, but do not show how to use a member of your own type
as the value being sought.

What does your favourite C++ book say? Don't you have a copy of
Josuttis' "The C++ Standard Library"? You can define your own
functor to compare the value of the 'x' member with the given value
and then call

std::find(container.begin(), container.end(), yourFunctor(42));

V
 
R

red floyd

Victor said:
"om" value? What's "om" value? Sorry, English is not my mother
tongue.


What does your favourite C++ book say? Don't you have a copy of
Josuttis' "The C++ Standard Library"? You can define your own
functor to compare the value of the 'x' member with the given value
and then call

std::find(container.begin(), container.end(), yourFunctor(42));

V

I think he wants remove_copy_if() with negated functor?

std::vector<MyClass> v;

struct hasElement: public std::unary_function<MyClass, bool>
{
bool operator()(const MyClass& elem) const
{
return elem.x == x;
}
hasElement(int x_) : x(x_) { }
private
int x;
};

std::remove_copy_if(container.begin(), container.end(),
std::back_inserter(v),
std::not(hasElement(42))_;
 
V

Victor Bazarov

red said:
I think he wants remove_copy_if() with negated functor?

std::vector<MyClass> v;

struct hasElement: public std::unary_function<MyClass, bool>
{
bool operator()(const MyClass& elem) const
{
return elem.x == x;
}
hasElement(int x_) : x(x_) { }
private
int x;
};

std::remove_copy_if(container.begin(), container.end(),
std::back_inserter(v),
std::not(hasElement(42))_;

I couldn't find the word "remove" in the original post. Only "get"
and "find". For that 'find' is called in a 'while' loop and the
beginning of the range should keep changing:

it = c.begin();
while (true) {
it = std::find(it, c.end(), hasElement(42));
if (it != c.end()) {
// do something with 'it' or with '*it' or with it->x or...
}
else
break;
}

V
 
D

David Harmon

On 14 Mar 2007 10:48:40 -0700 in comp.lang.c++, "brekehan"
If I have a class
MyClass
{
...bunch o data and methods
int x;
};

and a stl container of MyClass objects

Is there a way to use std::find to get all the elements whose member x
is of om value?

I think you might end up using std::find_if() with a predicate that
selects the values you want. The predicate could be a boost::lambda
expression, or it could be hand crafted. Since find() and find_if()
return just one thing, you could loop to find them all.

Some random fragments:

bool ifx(MyClass const & c, int x)
{ return c.x == x; }

for (iterator_type it = container.begin(); it != container.end();
it = find_if(it, container.end(), std::bind_2nd(ifx, om))) {
if (it != container.end())
cout << *it++;
}
 
B

brekehan

"om" value? What's "om" value? Sorry, English is not my mother
tongue.


What does your favourite C++ book say? Don't you have a copy of
Josuttis' "The C++ Standard Library"? You can define your own
functor to compare the value of the 'x' member with the given value
and then call

std::find(container.begin(), container.end(), yourFunctor(42));

V


om = some. this keyboard sucks. Sorry. I also used to have three
really good STL references, but the girlfriend got angry that I love
the computer more than her and disposed of most of my office. I plan
on getting some more, meantime I got a deadline to meet.

I see that a few of the functions in <algorithm> or the container
itself take the functor argument you mentioned, but if I understand
correctly this is passed 1 argument of the type contained. remove_if
would be awesome, because that is exatly what my goal is. Remove an
element if it has a member (we'll call it TYPE m_type) of some type.
However, I need to have two arguments...the element and the TYPE to
compare it with, so my functor can say is this element of this type?
Otherwise, I have to write a functor for every possible value of
m_type and there is no telling how many there may be in the future.
 
D

David Harmon

On 14 Mar 2007 11:35:52 -0700 in comp.lang.c++, "brekehan"
However, I need to have two arguments...the element and the TYPE to
compare it with, so my functor can say is this element of this type?
Otherwise, I have to write a functor for every possible value of
m_type and there is no telling how many there may be in the future.

Solving that part of the problem is the job of the std::bind* family.
Or else something more modern and powerful like boost::bind.
 
M

Marcus Kwok

brekehan said:
If I have a class
MyClass
{
...bunch o data and methods
int x;
};

and a stl container of MyClass objects

Is there a way to use std::find to get all the elements whose member x
is of om value?

I believe std::find by default uses std::less<T>, which by default uses
operator<. So, you can provide your own operator<, or explicitly
provide a comparison functor to find().

Then, one way would be to sort your container, then use std::lower_bound
and std::upper_bound.
 
R

red floyd

Victor said:
I couldn't find the word "remove" in the original post. Only "get"
and "find". For that 'find' is called in a 'while' loop and the
beginning of the range should keep changing:

it = c.begin();
while (true) {
it = std::find(it, c.end(), hasElement(42));
if (it != c.end()) {
// do something with 'it' or with '*it' or with it->x or...
}
else
break;
}

I thought remove_copy_if doesn't modify the original container. The
construct I gave should copy all elements with x == 42.
 

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

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,022
Latest member
MaybelleMa

Latest Threads

Top