CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 27
  1. #1
    Join Date
    Nov 2006
    Location
    Australia
    Posts
    1,569

    [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.
    Good judgment is gained from experience. Experience is gained from bad judgment.
    Cosy Little Game | SDL | GM script | VLD | Syntax Hlt | Can you help me with my homework assignment?

  2. #2
    Join Date
    Apr 2003
    Location
    kathmandu, nepal
    Posts
    1,570

    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

  3. #3
    Join Date
    Jan 2004
    Location
    Düsseldorf, Germany
    Posts
    2,401

    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.

  4. #4
    Join Date
    Nov 2006
    Location
    Australia
    Posts
    1,569

    Re: vector copy using new

    Quote 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.
    Good judgment is gained from experience. Experience is gained from bad judgment.
    Cosy Little Game | SDL | GM script | VLD | Syntax Hlt | Can you help me with my homework assignment?

  5. #5
    Join Date
    Nov 2006
    Location
    Essen, Germany
    Posts
    1,344

    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

  6. #6
    Join Date
    Nov 2006
    Location
    Australia
    Posts
    1,569

    Re: vector copy using new

    Quote 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.
    Good judgment is gained from experience. Experience is gained from bad judgment.
    Cosy Little Game | SDL | GM script | VLD | Syntax Hlt | Can you help me with my homework assignment?

  7. #7
    Join Date
    Jan 2004
    Location
    Düsseldorf, Germany
    Posts
    2,401

    Re: vector copy using new

    Quote 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.

  8. #8
    Join Date
    Nov 2006
    Location
    Australia
    Posts
    1,569

    Re: vector copy using new

    Quote 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); }
    };
    Quote 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?
    Good judgment is gained from experience. Experience is gained from bad judgment.
    Cosy Little Game | SDL | GM script | VLD | Syntax Hlt | Can you help me with my homework assignment?

  9. #9
    Join Date
    Jan 2006
    Location
    Singapore
    Posts
    6,765

    Re: vector copy using new

    D's override of clone() can return a D* instead. I believe this is the "covariant return type" thing.
    C + C++ Compiler: MinGW port of GCC
    Build + Version Control System: SCons + Bazaar

    Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
    Kindly rate my posts if you found them useful

  10. #10
    Join Date
    Nov 2006
    Location
    Essen, Germany
    Posts
    1,344

    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

  11. #11
    Join Date
    Jan 2004
    Location
    Düsseldorf, Germany
    Posts
    2,401

    Re: vector copy using new

    Quote 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.
    Quote 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.

  12. #12
    Join Date
    Jan 2004
    Location
    Düsseldorf, Germany
    Posts
    2,401

    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.

  13. #13
    Join Date
    Nov 2006
    Location
    Australia
    Posts
    1,569

    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?
    Good judgment is gained from experience. Experience is gained from bad judgment.
    Cosy Little Game | SDL | GM script | VLD | Syntax Hlt | Can you help me with my homework assignment?

  14. #14
    Join Date
    Jan 2004
    Location
    Düsseldorf, Germany
    Posts
    2,401

    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.

  15. #15
    Join Date
    Nov 2006
    Location
    Australia
    Posts
    1,569

    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.
    Good judgment is gained from experience. Experience is gained from bad judgment.
    Cosy Little Game | SDL | GM script | VLD | Syntax Hlt | Can you help me with my homework assignment?

Page 1 of 2 12 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured