|
-
November 10th, 2009, 04:40 PM
#1
member binary predicate problems!
Hi,
I want to use max_element with a predicate. I have 2 vectors stored in a class and I want to use min_element on one vector using a predicate which refers to the second. i.e. the first vector (seeds) holds indices referring to values in the second (nodes).
Code:
unsigned int Map::GetSeed()
{
unsigned int seed = 0;
if(seeds.size() > 1)
{
std::vector<unsigned int>::iterator iter;
iter = std::min_element(seeds.begin(),seeds.end(), XLesser);
seed = *iter;
seeds.erase(iter);
return seed;
}
if(seeds.size() == 1)
{
seed = seeds[0];
seeds.erase(seeds.begin());
return seed;
}
return seed;
}
where Xlesser is defined by
Code:
bool Map::XLesser(unsigned int index1, unsigned int index2)
{
return nodes[index1].x < nodes[index2].x;
}
My problem is that predicates are meant to have 2 arguments but XLesser will have 3 (the 3rd being a pointer to the object). I've read that this can be overcome by declaring XLesser as static but that doesn't work here because XLesser accesses the private vector nodes and I get error C2597: illegal reference to non-static member 'Map::nodes'! How do I get around this!?
For some explanation nodes holds vertices and seeds holds indices referring to certain vertices in nodes.
-
November 10th, 2009, 04:49 PM
#2
Re: member binary predicate problems!
If you have Boost, you can use boost::bind() to get around this.
If not, I'll explain what bind() is actually doing in this case.
See, the predicate doesn't need to be a function. A functor will do just as well. So if you write a trivial functor which takes in a pointer to a Map in its constructor, and has operator() defined to take two ints, it can call m->XLesser() within its operator().
-
November 11th, 2009, 06:37 AM
#3
Re: member binary predicate problems!
Thanks very much for the reply. I am using boost but would prefer to implement things myself the first time to make sure I understand what is going on! After reading about functors a bit here's what I've done:
I have a class defined as:
Code:
class Functor
{
Map* map_pt;
public:
Functor(Map* _map_pt) : map_pt(_map_pt)
{
}
bool operator()(unsigned int index1, unsigned int index2)
{
return map_pt->XLesser(index1, index2);
}
};
and now my GetSeed function looks like this:
Code:
unsigned int Map::GetSeed()
{
static Functor functor(this);
unsigned int seed = 0;
if(seeds.size() > 1)
{
std::vector<unsigned int>::iterator iter;
iter = std::min_element(seeds.begin(),seeds.end(), functor);
seed = *iter;
seeds.erase(iter);
return seed;
}
if(seeds.size() == 1)
{
seed = seeds[0];
seeds.erase(seeds.begin());
return seed;
}
return seed;
}
Is what you meant and how it should be done?
Last edited by bibalasvegas; November 11th, 2009 at 08:43 AM.
-
November 11th, 2009, 11:10 AM
#4
Re: member binary predicate problems!
You probably don't want to make the functor a static variable. It would then only be initialized the first time that Map::GetSeed is called. This would be bad if you have more than one Map object.
Instead, you can directly create a Functor object in the call to min_element:
Code:
iter = std::min_element(seeds.begin(),seeds.end(), Functor(this));
-
November 11th, 2009, 12:03 PM
#5
Re: member binary predicate problems!
Yes, good advice!
Thanks again.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|