-
January 6th, 2009, 10:58 AM
#1
Addressof Unary Functor
Hi,
I have an vector of objects
Code:
std::vector<Class> v1;
and now I want to make a vector of Class *, which index pointing to a element in v1. for example
Code:
std::vector<Class *> v2;
v2[0] = &v1[0]
I can easily do this by writing the following loop
Code:
v2.reserve ( v1.size() );
for (vector<Class>::iterator it = v1.begin(); it != v1.end(); it++) {
v2.push_back ( &(*it) );
}
But I wanted to do this in a more STL style way, so I used a transform:
Code:
transform (v1.begin(), v1.territories.end(), v2.begin(), addressof<Class>() );
However, the addressof unary functor doesn't exist, so I coded one like so:
Code:
template <class T> struct addressof : std::unary_function <T,T> {
T* operator() (T& x) const
{return &x;}
};
Now my two questions are,
1) Does a functor like addressof already exist?
2) Is there anything wrong/weird with my approach?
I wanted to create an array of Class *, so I could quickly shuffle the array without copying the class instance many times. e.g.
Code:
random_shuffle ( v2.begin(), v2.end() );
I know that my v2 array will contain invalid pointers if v1 changes, however, once v1 is setup it will never grow/shrink.
thanks
Andrew
-
January 6th, 2009, 11:47 AM
#2
Re: Addressof Unary Functor
Originally Posted by bramp
Now my two questions are,
1) Does a functor like addressof already exist?
None that I'm aware of.
Originally Posted by bramp
2) Is there anything wrong/weird with my approach?
Seems fine to me. It did seem a bit odd that you would create a second array of pointers to every element in another array, but then I saw the last part of your post. You might avoid the invalid pointer thing by storing indexes in the second array instead of pointers, though.
- Alon
-
January 7th, 2009, 11:19 AM
#3
Re: Addressof Unary Functor
Originally Posted by bramp
I know that my v2 array will contain invalid pointers if v1 changes, however, once v1 is setup it will never grow/shrink.
...until a day or two after this assumption gets deeply embedded into the code, at which point the requirements will change in such a way as to make the assumption invalid.
Cynical? Me?
But it will happen...
Correct is better than fast. Simple is better than complex. Clear is better than cute. Safe is better than insecure.
-- Sutter and Alexandrescu, C++ Coding Standards
Programs must be written for people to read, and only incidentally for machines to execute.
-- Harold Abelson and Gerald Jay Sussman
The cheapest, fastest and most reliable components of a computer system are those that aren't there.
-- Gordon Bell
-
January 7th, 2009, 12:22 PM
#4
Re: Addressof Unary Functor
Originally Posted by Graham
Cynical? Me?
But it will happen...
A little paranoid perhaps, but I am aware of the problem.
Well just out of interest, lets consider a different solutions, but first I will provide some background.
I'm creating a program to play the game Risk. Risk has a fixed number of territories (countries) that you try and conquer. I create one instance of a Territory class for each territory on the map and store it in my vector v1. Now I know that the number will stay fixed for the duration of the game, hence I'm not worried that v1 will change. However, if we want to be paranoid and assume it might, would the correct way be to store pointers to new'd Territory classes?
The reason I didn't want to use new, was that if the object pointer is removed from the vector it is not automatically delete'd, whereas if I don't store pointers it is. eg:
Code:
Vector <Class *> v1;
v1.push_back ( new Class("England") );
v1.push_back ( new Class("France") );
// some time latter
v1.clear();
// Now I've leaked memory, because I forgot to remove (and delete) one by one
Now since several parts of my code needs access to these Territory classes I will only ever pass pointers or references to the instances stored in the vector, i.e
Code:
Vector <Class> v1;
v1.push_back ( Class("England") );
// some where else
Class *blah = &v1[0];
So I see no problem doing this unless the vector is changed mid-game.
Maybe someone can suggest a different approach, or perhaps why using new/delete is still better? Or suggest a way to guarantee I don't leak memory if I clear the vector<Class *>.
thanks
Andrew
-
January 7th, 2009, 01:14 PM
#5
Re: Addressof Unary Functor
Originally Posted by bramp
The reason I didn't want to use new, was that if the object pointer is removed from the vector it is not automatically delete'd, whereas if I don't store pointers it is.
You may want to have a look at boost's ptr_vector class. It will, by default, automatically delete pointers when they are removed from the container.
Another option would be to use a vector of smart pointers. In this case you can use tr1::shared_ptr, which unlike the boost libraries probably comes with your compiler.
Last edited by Hermit; January 7th, 2009 at 01:17 PM.
- Alon
-
January 7th, 2009, 04:35 PM
#6
Re: Addressof Unary Functor
Hello bramp
I'm not 100% sure about what I'm about to say, so plz bear with me!
If the point of removing a territory class (v1.clear()) is to indicate that the territory has been conquered, then, I don't think removing it from the vector is the best choice in this case.
because it can only signal two state of conditions.
how about you create a table of function objects to point to each territory class,
and use the pointer to indicate the current state of the territory?
So in this way, you not only have more options to indicate territory's current conditions,
but don't have to worry too much about having those map classes on the heap.
but then again..i think you need a global member (but not static) to do that.
hm, does this any make sense to you?
hm...i don't know.
Last edited by potatoCode; January 7th, 2009 at 04:37 PM.
Reason: caught an error
-
January 8th, 2009, 07:20 AM
#7
Re: Addressof Unary Functor
One other option could be to store your data in a std::list instead of a std::vector. Then random_shuffle would not be so great an overhead as the data itself will not move.
"It doesn't matter how beautiful your theory is, it doesn't matter how smart you are. If it doesn't agree with experiment, it's wrong."
Richard P. Feynman
-
January 8th, 2009, 07:44 AM
#8
Re: Addressof Unary Functor
Originally Posted by JohnW@Wessex
One other option could be to store your data in a std::list instead of a std::vector. Then random_shuffle would not be so great an overhead as the data itself will not move.
random_shuffle() needs a random access iterator...
Correct is better than fast. Simple is better than complex. Clear is better than cute. Safe is better than insecure.
-- Sutter and Alexandrescu, C++ Coding Standards
Programs must be written for people to read, and only incidentally for machines to execute.
-- Harold Abelson and Gerald Jay Sussman
The cheapest, fastest and most reliable components of a computer system are those that aren't there.
-- Gordon Bell
-
January 8th, 2009, 07:47 AM
#9
Re: Addressof Unary Functor
Originally Posted by potatoCode
I'm not 100% sure about what I'm about to say, so plz bear with me!
If the point of removing a territory class (v1.clear()) is to indicate that the territory has been conquered, then, I don't think removing it from the vector is the best choice in this case.
because it can only signal two state of conditions.
Sorry, I think you miss understood... The vector of territories will not change throughout the game. It is a list of all territories, not just the ones which aren't conquered.
I will have other vectors storing which are owned by which player, and which aren't conquered, etc. But these will be vectors of pointers.
Last edited by bramp; January 8th, 2009 at 07:58 AM.
-
January 8th, 2009, 08:53 AM
#10
Re: Addressof Unary Functor
Originally Posted by Graham
random_shuffle() needs a random access iterator...
Yes, of course
How about the data in a std::list and calling 'next permutation' a random number of times. A bit clunky I know, but maybe worth considering.
"It doesn't matter how beautiful your theory is, it doesn't matter how smart you are. If it doesn't agree with experiment, it's wrong."
Richard P. Feynman
Tags for this Thread
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
|