|
-
January 28th, 2008, 09:09 AM
#1
[RESOLVED] vector copy using new
Hey.
I'm wanting to fill the vector below with newed copies of each element in vec_ref and I was wondering if there is a STL algorithm that I can take advantage of?
Code:
int main()
{
std::vector<C> c_vec(10, C(1));
const std::vector<C>& vec_ref = c_vec;
std::vector<C*> new_c_vec;
// ... copy vec_ref into new_c_vec using "new"
return 0;
}
Cheers.
-
January 28th, 2008, 09:56 AM
#2
Re: vector copy using new
I find your question a little confusing. You say "newed copies" at the same time "of each element in vec_ref".
Last edited by miteshpandey; January 28th, 2008 at 09:58 AM.
If there is no love sun won't shine
-
January 28th, 2008, 10:04 AM
#3
Re: vector copy using new
I think, a reasonable way of achieving this is to provide a clone() function for your class and then use std::transform.
Code:
class C {
// ...
virtual C* clone() { return new C(*this); }
}
Call to transform should look something like (not tested):
Code:
std::transform(c_vec.begin(), c_vec.end(),
std::back_inserter(new_c_vec),
mem_fun_ref(clone));
or, if you resize new_c_vec before like
Code:
std::transform(c_vec.begin(), c_vec.end(),
new_c_vec.begin(),
mem_fun_ref(clone));
Last edited by treuss; January 28th, 2008 at 10:09 AM.
More computing sins are committed in the name of efficiency (without necessarily achieving it) than for any other single reason - including blind stupidity. --W.A.Wulf
Premature optimization is the root of all evil --Donald E. Knuth
Please read Information on posting before posting, especially the info on using [code] tags.
-
January 28th, 2008, 10:43 AM
#4
Re: vector copy using new
 Originally Posted by treuss
I think, a reasonable way of achieving this is to provide a clone() function for your class and then use std::transform.
Code:
class C {
// ...
virtual C* clone() { return new C(*this); }
}
Call to transform should look something like (not tested):
Code:
std::transform(c_vec.begin(), c_vec.end(),
std::back_inserter(new_c_vec),
mem_fun_ref(clone));
or, if you resize new_c_vec before like
Code:
std::transform(c_vec.begin(), c_vec.end(),
new_c_vec.begin(),
mem_fun_ref(clone));
Nice idea! But in this case would it be better just to iterate through c_vec and push_back new Cs instead of creating the clone function? It won't be hard to change the classes that rely on this, but I'm just wondering which option you think is more professional.
Cheers.
-
January 28th, 2008, 11:05 AM
#5
Re: vector copy using new
Please describe what you are going to do with the copied elements. Maybe it isn´t necessary to clone the vector by choosing a different approach than the one you´re implementing now.
- Guido
-
January 28th, 2008, 11:14 AM
#6
Re: vector copy using new
 Originally Posted by GNiewerth
Please describe what you are going to do with the copied elements. Maybe it isn´t necessary to clone the vector by choosing a different approach than the one you´re implementing now.
Code:
// Update screen elements.
test_screen.Update(event_);
// Draw(blit) elements to screen.
test_screen.Draw(DE.Get_Screen());
// Draw screen.
DE.Draw_Screen();
In the real problem, they're going to be stored in a vector of base pointers (Base_XImage) which itself is stored in my Screen class. From there, each time Update or Draw gets called as above, each element in the vector of base pointers will have Update and Draw called polymorphically. The class hierarchy looks like this:
Code:
Base_XImage
XImage
XButton
Last edited by Mybowlcut; January 28th, 2008 at 11:17 AM.
-
January 28th, 2008, 11:32 AM
#7
Re: vector copy using new
 Originally Posted by Mybowlcut
Nice idea! But in this case would it be better just to iterate through c_vec and push_back new Cs instead of creating the clone function? It won't be hard to change the classes that rely on this, but I'm just wondering which option you think is more professional.
Basically I see three options:- A clone function and using std::transform with mem_fun_ref
- A free function for cloning and using std::transform with the free function
- Not using std::transform but writing the loop yourself and creating the clone inline inside the loop
I'm not 100% sure, I understand your last post correctly, but if C is in fact a base class, I would definitely create the clone function. Note that the function should be virtual and all derived classes should of course return a pointer to a derived class. You will soon find that the clone function has a lot of uses. Think about creating a deep copy of a vector of base class pointers. Piece of cake ;-)
More computing sins are committed in the name of efficiency (without necessarily achieving it) than for any other single reason - including blind stupidity. --W.A.Wulf
Premature optimization is the root of all evil --Donald E. Knuth
Please read Information on posting before posting, especially the info on using [code] tags.
-
January 28th, 2008, 11:43 AM
#8
Re: vector copy using new
 Originally Posted by treuss
Basically I see three options: - A clone function and using std::transform with mem_fun_ref
- A free function for cloning and using std::transform with the free function
- Not using std::transform but writing the loop yourself and creating the clone inline inside the loop
I'm not 100% sure, I understand your last post correctly, but if C is in fact a base class, I would definitely create the clone function. Note that the function should be virtual and all derived classes should of course return a pointer to a derived class.
Do you mean like this?
Code:
class C
{
public:
C(int x_) : x(x_) {}
virtual C* clone() { return new C(*this); }
int x;
};
class D : public C
{
D(int x) : C(x) {}
virtual C* clone() { return new D(*this); }
};
 Originally Posted by treuss
You will soon find that the clone function has a lot of uses. Think about creating a deep copy of a vector of base class pointers. Piece of cake ;-)
It sounds good hey haha. Have you used this kind of function before?
-
January 28th, 2008, 11:49 AM
#9
Re: vector copy using new
D's override of clone() can return a D* instead. I believe this is the "covariant return type" thing.
-
January 28th, 2008, 12:00 PM
#10
Re: vector copy using new
What about a custom function object?
Code:
struct DrawFunc
{
Screen S_;
Event E_;
DrawFunc( Screen& s, Event& e ) : S_( s ), E_( e )
{
}
void operator()( C* pObj )
{
// do whatever you need to do with C, S_ and E_
}
}
std::vector<C*> c_vec;
for_each( c_vec.begin(), c_vec.end(), DrawFunc( theScreen, theEvent ) );
I just wrote this lines down, I´m pretty sure they won´t compile, but i hope you got the idea.
- Guido
-
January 28th, 2008, 12:18 PM
#11
Re: vector copy using new
 Originally Posted by Mybowlcut
Do you mean like this?
Better:
Code:
virtual D* clone() { return new D(*this); }
And of course you are lacking the virtual destructor in the example.
 Originally Posted by Mybowlcut
It sounds good hey haha. Have you used this kind of function before?
Yes and I think it is a common design pattern, I just can't recall where I first read about it (Scott Meyers' probably).
More computing sins are committed in the name of efficiency (without necessarily achieving it) than for any other single reason - including blind stupidity. --W.A.Wulf
Premature optimization is the root of all evil --Donald E. Knuth
Please read Information on posting before posting, especially the info on using [code] tags.
-
January 28th, 2008, 02:36 PM
#12
Re: vector copy using new
More computing sins are committed in the name of efficiency (without necessarily achieving it) than for any other single reason - including blind stupidity. --W.A.Wulf
Premature optimization is the root of all evil --Donald E. Knuth
Please read Information on posting before posting, especially the info on using [code] tags.
-
January 29th, 2008, 01:26 AM
#13
Re: vector copy using new
Ok. I made the interface class Cloneable:
Code:
class Cloneable
{
public:
virtual ~Cloneable() {}
virtual Cloneable* Clone() = 0;
};
Then derived my base class from it:
Code:
class Base_XImage : public Drawable, public Updateable, public Cloneable
{
public:
Base_XImage();
Base_XImage(
const std::string& file_name_,
int position_x,
int position_y,
bool is_colour_key_,
SDL_Colour colour_key_ = SDL_Wrappers::colour(0,0,0));
Base_XImage(const Base_XImage& rhs);
virtual ~Base_XImage();
Base_XImage& operator=(const Base_XImage& rhs);
const std::string& Get_File_Name() const;
const SDL_Rect& Get_Position() const;
bool Is_Colour_Key() const;
const SDL_Colour& Get_Colour_Key() const;
virtual void Load() = 0;
virtual void Draw(SDL_Surface* screen) = 0;
virtual void Update(const SDL_Event& event_) = 0;
virtual Base_XImage* Clone() = 0;
protected:
std::string file_name;
SDL_Rect position;
bool is_colour_key;
SDL_Colour colour_key;
SDL_Surface* surface;
};
Then I tried to use transform with it (buttons is a vector of XButtons which derive from Base_XImage:
Code:
std::transform(buttons.begin(), buttons.end(),
std::back_inserter(elements), std::mem_fun_ref(&Base_XImage::Clone));
Code:
Error 1 error C2784: 'std::const_mem_fun1_ref_t<_Result,_Ty,_Arg> std::mem_fun_ref(_Result (__thiscall _Ty::* )(_Arg) const)' : could not deduce template argument for 'overloaded function type' from 'overloaded function type' c:\documents and settings\user\my documents\visual studio 2005\projects\sdl_game_engine\sdl_game_engine\screen.cpp 68
Error 2 error C2784: 'std::const_mem_fun1_ref_t<_Result,_Ty,_Arg> std::mem_fun_ref(_Result (__thiscall _Ty::* )(_Arg) const)' : could not deduce template argument for 'overloaded function type' from 'overloaded function type' c:\documents and settings\user\my documents\visual studio 2005\projects\sdl_game_engine\sdl_game_engine\screen.cpp 68
Error 3 error C2784: 'std::const_mem_fun1_ref_t<_Result,_Ty,_Arg> std::mem_fun_ref(_Result (__thiscall _Ty::* )(_Arg) const)' : could not deduce template argument for 'overloaded function type' from 'overloaded function type' c:\documents and settings\user\my documents\visual studio 2005\projects\sdl_game_engine\sdl_game_engine\screen.cpp 68
Error 4 error C2914: 'std::mem_fun_ref' : cannot deduce template argument as function argument is ambiguous c:\documents and settings\user\my documents\visual studio 2005\projects\sdl_game_engine\sdl_game_engine\screen.cpp 68
Error 5 error C2784: 'std::const_mem_fun_ref_t<_Result,_Ty> std::mem_fun_ref(_Result (__thiscall _Ty::* )(void) const)' : could not deduce template argument for 'overloaded function type' from 'overloaded function type' c:\documents and settings\user\my documents\visual studio 2005\projects\sdl_game_engine\sdl_game_engine\screen.cpp 68
Error 6 error C2784: 'std::mem_fun1_ref_t<_Result,_Ty,_Arg> std::mem_fun_ref(_Result (__thiscall _Ty::* )(_Arg))' : could not deduce template argument for 'overloaded function type' from 'overloaded function type' c:\documents and settings\user\my documents\visual studio 2005\projects\sdl_game_engine\sdl_game_engine\screen.cpp 68
Error 7 error C2784: 'std::mem_fun1_ref_t<_Result,_Ty,_Arg> std::mem_fun_ref(_Result (__thiscall _Ty::* )(_Arg))' : could not deduce template argument for 'overloaded function type' from 'overloaded function type' c:\documents and settings\user\my documents\visual studio 2005\projects\sdl_game_engine\sdl_game_engine\screen.cpp 68
Error 8 error C2784: 'std::mem_fun1_ref_t<_Result,_Ty,_Arg> std::mem_fun_ref(_Result (__thiscall _Ty::* )(_Arg))' : could not deduce template argument for 'overloaded function type' from 'overloaded function type' c:\documents and settings\user\my documents\visual studio 2005\projects\sdl_game_engine\sdl_game_engine\screen.cpp 68
Error 9 error C2914: 'std::mem_fun_ref' : cannot deduce template argument as function argument is ambiguous c:\documents and settings\user\my documents\visual studio 2005\projects\sdl_game_engine\sdl_game_engine\screen.cpp 68
Error 10 error C2784: 'std::mem_fun_ref_t<_Result,_Ty> std::mem_fun_ref(_Result (__thiscall _Ty::* )(void))' : could not deduce template argument for 'overloaded function type' from 'overloaded function type' c:\documents and settings\user\my documents\visual studio 2005\projects\sdl_game_engine\sdl_game_engine\screen.cpp 68
Error 11 error C2780: '_OutIt std::transform(_InIt1,_InIt1,_InIt2,_OutIt,_Fn2)' : expects 5 arguments - 4 provided c:\documents and settings\user\my documents\visual studio 2005\projects\sdl_game_engine\sdl_game_engine\screen.cpp 68
Anyone know what this is complaining about?
-
January 29th, 2008, 05:57 AM
#14
Re: vector copy using new
Beautiful error messages 
No idea, the call to transform looks correct. Try compiling the following (works with g++ and comeau), if that works try correcting your code accordingly. Or post a compilable sample of the problem 
Code:
#include <vector>
#include <algorithm>
#include <functional>
class Base
{
public:
virtual Base * clone() const = 0;
virtual ~Base() {}
};
class Derived : public Base
{
public:
virtual Derived * clone() const { return new Derived(*this); }
virtual ~Derived() {}
};
int main()
{
std::vector<Derived> v1(3);
std::vector<Base*> v2(3);
std::transform(v1.begin(), v1.end(),
v2.begin(),
std::mem_fun_ref(&Base::clone));
std::vector<Base*> v3;
std::transform(v1.begin(), v1.end(),
std::back_inserter(v3),
std::mem_fun_ref(&Base::clone));
}
EDIT: Just noticed that your clone function is not const. Don't know if that matters but it should of course be.
More computing sins are committed in the name of efficiency (without necessarily achieving it) than for any other single reason - including blind stupidity. --W.A.Wulf
Premature optimization is the root of all evil --Donald E. Knuth
Please read Information on posting before posting, especially the info on using [code] tags.
-
January 29th, 2008, 10:14 AM
#15
Re: vector copy using new
Could it be that buttons is a vector of objects whilst elements is a vector of object pointers? Unfortunately I can't really post a working example as my code uses a third party library.
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
|