473,394 Members | 1,869 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,394 software developers and data experts.

using find_if/binary_function


I have a vector of class object pointers that have 2 internal states
(USED or EMPTY). USED is just a way of indicating the element in that
slot has valid state. EMPTY means the element is available for re-use.

I was trying to write some code to locate an used element using find_if
with a custom predicate derived from unary_function. That was pretty
easy. I however wanted something else. If the element cannot be
located, I wanted to return the index of the first (or for that matter
*any*) empty slot. I am trying to do this in one pass without having
to write another predicate to test for empty slots. I was about to
write something like this:

struct no_op
{
string my_name;
no_op() : my_name("default_name") { }
no_op(string _my_name) : my_name(_my_name) { }
void cleanthyself() { my_name = "EMPTY_SLOT"; }
};

typedef vector<no_op*> vecNoOps;

struct oplocator : public binary_function<no_op, short, bool>
{
string _name;
explicit oplocator(const string& name) : _name(name) { }
bool operator()(const no_op* opobj, short& emptyslotIdx) const
{
static int i = 0;
++i;
if (opobj->my_name == _name) return true;
if (opobj->my_name == "EMPTY_SLOT") { emptyslotIdx = i; }
return false;
}
};

I thought on the client side I will just try to locate the element I am
interested in as usual and if I reach the end of the vector without
locating I will atleast have the index of the empty slot. I also
thought I'd use some kind of default value for emptyslotIdx to tell if
I was able to found an emptyslot at all. If nothing is available I
will simply create a new object.

After reading Meyers' Effective STL item 39 I am no longer sure. He
wants developers to avoid exactly this kind of programming (maintaining
a local static).

Is there a way to do what I want without having to make 2 passes at the
vector of no_ops?

thanks!

May 25 '06 #1
6 2634
Dilip wrote:
I have a vector of class object pointers that have 2 internal states
(USED or EMPTY). USED is just a way of indicating the element in that
slot has valid state. EMPTY means the element is available for re-use.

I was trying to write some code to locate an used element using find_if
with a custom predicate derived from unary_function. That was pretty
easy. I however wanted something else. If the element cannot be
located, I wanted to return the index of the first (or for that matter
*any*) empty slot. I am trying to do this in one pass without having
to write another predicate to test for empty slots. I was about to
write something like this:

struct no_op
{
string my_name;
no_op() : my_name("default_name") { }
no_op(string _my_name) : my_name(_my_name) { }
void cleanthyself() { my_name = "EMPTY_SLOT"; }
};

typedef vector<no_op*> vecNoOps;

struct oplocator : public binary_function<no_op, short, bool>
{
string _name;
explicit oplocator(const string& name) : _name(name) { }
bool operator()(const no_op* opobj, short& emptyslotIdx) const
{
static int i = 0;
++i;
if (opobj->my_name == _name) return true;
if (opobj->my_name == "EMPTY_SLOT") { emptyslotIdx = i; }
return false;
}
};

I thought on the client side I will just try to locate the element I am
interested in as usual and if I reach the end of the vector without
locating I will atleast have the index of the empty slot. I also
thought I'd use some kind of default value for emptyslotIdx to tell if
I was able to found an emptyslot at all. If nothing is available I
will simply create a new object.

After reading Meyers' Effective STL item 39 I am no longer sure. He
wants developers to avoid exactly this kind of programming (maintaining
a local static).

Is there a way to do what I want without having to make 2 passes at the
vector of no_ops?


Do a manual loop in a separate function. Clean and simple.
Jonathan

May 25 '06 #2
In article <11*********************@u72g2000cwu.googlegroups. com>,
"Dilip" <rd*****@lycos.com> wrote:
I have a vector of class object pointers that have 2 internal states
(USED or EMPTY). USED is just a way of indicating the element in that
slot has valid state. EMPTY means the element is available for re-use.

I was trying to write some code to locate an used element using find_if
with a custom predicate derived from unary_function. That was pretty
easy. I however wanted something else. If the element cannot be
located, I wanted to return the index of the first (or for that matter
*any*) empty slot. I am trying to do this in one pass without having
to write another predicate to test for empty slots. I was about to
write something like this:

struct no_op
{
string my_name;
no_op() : my_name("default_name") { }
no_op(string _my_name) : my_name(_my_name) { }
void cleanthyself() { my_name = "EMPTY_SLOT"; }
};

typedef vector<no_op*> vecNoOps;

struct oplocator : public binary_function<no_op, short, bool>
{
string _name;
explicit oplocator(const string& name) : _name(name) { }
bool operator()(const no_op* opobj, short& emptyslotIdx) const
{
static int i = 0;
++i;
if (opobj->my_name == _name) return true;
if (opobj->my_name == "EMPTY_SLOT") { emptyslotIdx = i; }
return false;
}
};

I thought on the client side I will just try to locate the element I am
interested in as usual and if I reach the end of the vector without
locating I will atleast have the index of the empty slot. I also
thought I'd use some kind of default value for emptyslotIdx to tell if
I was able to found an emptyslot at all. If nothing is available I
will simply create a new object.

After reading Meyers' Effective STL item 39 I am no longer sure. He
wants developers to avoid exactly this kind of programming (maintaining
a local static).

Is there a way to do what I want without having to make 2 passes at the
vector of no_ops?


You are just looking for the first place to put something right?

find_if( vec.begin(), vec.end(), is_available() );

struct is_available : unary_function< no_op, bool >
{
bool operator()( const no_op* o ) const {
bool result = false;
if ( !o || o->my_name == "EMPTY_SLOT" )
result = true;
return result;
}
};

QED
May 26 '06 #3
Daniel T. wrote:
You are just looking for the first place to put something right?

find_if( vec.begin(), vec.end(), is_available() );

struct is_available : unary_function< no_op, bool >
{
bool operator()( const no_op* o ) const {
bool result = false;
if ( !o || o->my_name == "EMPTY_SLOT" )
result = true;
return result;
}
};


Daniel
Thanks for your efforts.
Actually I am trying to:

1) locate an element first
2) if that element is not found, find first empty slot
3) if empty slot is also not found, don't bother with anything in the
functor -- the client will simply add a new element in to the vector.

i want to do all of this in one pass.

it may not be possible in which case i will simply make 2 passes with
the functor. one to find the element and another to locate an empty
slot if the element is not found.

locating an element would involve searching for it by name -- just like
I search for "EMPTY_SLOT".
i would never have a need to check with pointer validity (!o) because I
have arranged for my pointers to always be valid with some zombie state
to differentiate them from objects with real state.

May 26 '06 #4

Dilip wrote:
Daniel T. wrote:
You are just looking for the first place to put something right?

find_if( vec.begin(), vec.end(), is_available() );

struct is_available : unary_function< no_op, bool >
{
bool operator()( const no_op* o ) const {
bool result = false;
if ( !o || o->my_name == "EMPTY_SLOT" )
result = true;
return result;
}
};


Daniel
Thanks for your efforts.
Actually I am trying to:

1) locate an element first
2) if that element is not found, find first empty slot
3) if empty slot is also not found, don't bother with anything in the
functor -- the client will simply add a new element in to the vector.

i want to do all of this in one pass.

it may not be possible in which case i will simply make 2 passes with
the functor. one to find the element and another to locate an empty
slot if the element is not found.


It is possible:

# include <algorithm>
# include <string>
# include <vector>

struct s
{
enum states
{
empty,
used
};

std::string name;
states state;
};

typedef std::vector<s> cont;

// returns an iterator to the element of name
// 'name' or, if it is not found, an iterator to
// the first empty element. if there is none, it
// returns c.end()
//
cont::iterator find(cont& c, const std::string& name)
{
cont::iterator empty_element = c.end();
for (cont::iterator itor=c.begin();
itor!=c.end();
++itor)
{
if (itor->name == name)
return itor;

if ((empty_element == c.end()) &&
(itor->state == s::empty))
{
empty_element = itor;
}
}

return empty_element;
}
Jonathan

May 26 '06 #5
In article <11*********************@u72g2000cwu.googlegroups. com>,
"Dilip" <rd*****@lycos.com> wrote:
Daniel T. wrote:
You are just looking for the first place to put something right?

find_if( vec.begin(), vec.end(), is_available() );

struct is_available : unary_function< no_op, bool >
{
bool operator()( const no_op* o ) const {
bool result = false;
if ( !o || o->my_name == "EMPTY_SLOT" )
result = true;
return result;
}
};
Daniel
Thanks for your efforts.
Actually I am trying to:

1) locate an element first
2) if that element is not found, find first empty slot
3) if empty slot is also not found, don't bother with anything in the
functor -- the client will simply add a new element in to the vector.

i want to do all of this in one pass.


If you use the above functor, that will happen as a matter of course.
Think about it, the vector starts with all NULLs so the functor will
return the 1st slot. The second time through, it will either return the
first slot (if "EMPTY_SLOT" is true) or the 2nd slot (if "EMPTY_SLOT" is
false on the first element.)

i would never have a need to check with pointer validity (!o) because I
have arranged for my pointers to always be valid with some zombie state
to differentiate them from objects with real state.


Well, I'm not so sure how useful that is, but I thought "EMPTY_SLOT" was
the zombie state. OK, I see what you want. This can work if you move all
the EMPTY_SLOTs to the back of the container first.

struct has_name_or_empty : unary_function< no_op, bool >
{
string name;
has_name_or_empty( const string& name_ ): name( name_ ) { }
bool operator()( const no_op* o ) const {
return o->my_name == "EMPTY_SLOT" || o->my_name == name;
}
};
remove( vec.begin(), vec.end(), has_name_or_empty( "EMPTY_SLOT" ) );
find_if( vec.begin(), vec.end(), has_name_or_empty( theName ) );

That will move all the "empty" elements to the end then get what you
want. However, this is effectively going through the container twice.

There is probably something you can do with for_each, you are allowed to
use statefull functors in it... However, it's sounding like you should
just write your own algorithm:

template < typename FwIt >
FwIt find_name_or_empty( FwIt first, FwIt last, const string& name )
{
typename FwIt candidate = last;
while ( first != last ) {
if ( (*first)->my_name == name ) return first;
if ( candidate == last && (*first)->my_name == "EMPTY_SLOT" )
candidate = first;
++first;
}
return candidate;
}

You might want to work to make that a little more generic.
May 26 '06 #6
In article <11*********************@u72g2000cwu.googlegroups. com>,
"Dilip" <rd*****@lycos.com> wrote:
Daniel T. wrote:
You are just looking for the first place to put something right?

find_if( vec.begin(), vec.end(), is_available() );

struct is_available : unary_function< no_op, bool >
{
bool operator()( const no_op* o ) const {
bool result = false;
if ( !o || o->my_name == "EMPTY_SLOT" )
result = true;
return result;
}
};


Daniel
Thanks for your efforts.
Actually I am trying to:

1) locate an element first
2) if that element is not found, find first empty slot
3) if empty slot is also not found, don't bother with anything in the
functor -- the client will simply add a new element in to the vector.

i want to do all of this in one pass.

it may not be possible in which case i will simply make 2 passes with
the functor. one to find the element and another to locate an empty
slot if the element is not found.

locating an element would involve searching for it by name -- just like
I search for "EMPTY_SLOT".
i would never have a need to check with pointer validity (!o) because I
have arranged for my pointers to always be valid with some zombie state
to differentiate them from objects with real state.


Dilip,

I was at dinner wondering why I never had this kind of problem myself
and it occurs to me that you are making things much harder on yourself
by insisting on keeping zombie objects around. Why is that? If you just
removed the objects, things will be much easer.

Another option that I just thought of. When an object goes zombie, swap
it with the last non-zombie in the vector. That way, all the zombies
will be kept at the end of the vector and the find_if functor will be
easy to do without having to go through the container twice. Of course
this would only work if the order of the objects is unimportant...
May 27 '06 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
by: Michael | last post by:
Hi, I'm having a few problems getting the following find_if to work class Entity { }; class factory {
2
by: Matthias Kaeppler | last post by:
Hello, I am having trouble getting std::equal_range to perform as I wish, and I can't find my error. Here's the situation: I have a vector of pointers to filesystem path objects (a file list,...
5
by: dave_if | last post by:
I have a vector of TCard objects, I am sorting them based on the the box field. That part works fine (finally!). I would then like to random_shuffle all cards that are in a particular box, that is,...
18
by: ma740988 | last post by:
Trying to get more acclimated with the use of function objects. As part of my test, consider: # include <vector> # include <iostream> # include <algorithm> #include <stdexcept> #include...
7
by: tehn.yit.chin | last post by:
I am trying to experiment <algorithm>'s find to search for an item in a vector of struct. My bit of test code is shown below. #include <iostream> #include <vector> #include <algorithm>...
5
by: google | last post by:
Hi All, I'm just getting started learning to use <algorithm> instead of loads of little for loops, and I'm looking for a bit of advice/mentoring re: implementing the following... I have a...
1
by: AlanJSmith | last post by:
can some clever guru help please. I am porting some C++ 6.0 projects to C++ VS2005 and find_if no longer exists in vector, i am not sure what to do. i am only at begginer level so please dont get...
10
by: JDT | last post by:
Hi, The following find_if works fine to me except that I want the internal individual comparison performed backward (from m+5, m+4, ..., to m). I can use reverse() to reverse the array first...
7
by: Anonymous | last post by:
I have map variable that maps ids (unsigned int) to objects. Each object has a Name() method. I want to use std::find_if to fetch the object that name matches. I defined my predicate like...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.