Thread: I need to better understand unique_ptr; allow me to pick your brain

  1. #1
    Registered User
    Join Date
    May 2010
    Posts
    178

    I need to better understand unique_ptr; allow me to pick your brain

    I wrote some code that produces this:

    Code:
    1>c:\users\comp sci\documents\visual studio 2010\projects\predatorpreysimulation\predatorpreysimulation\world.h(25): error C2665: 'std::vector<_Ty>::vector' : none of the 7 overloads could convert all the argument types
    1>          with
    1>          [
    1>              _Ty=World::UniqueOrganism
    1>          ]
    1>          c:\microsoft visual studio 10.0\vc\include\vector(521): could be 'std::vector<_Ty>::vector(unsigned int,const _Ty &)'
    1>          with
    1>          [
    1>              _Ty=World::UniqueOrganism
    1>          ]
    1>          while trying to match the argument list '(int, nullptr)'
    1>
    1>Build FAILED.
    The code producing such errors is:

    Code:
    class World{
    
    	struct UniqueOrganism{
    		std::unique_ptr<Organism> unique_organism;
    		
    		UniqueOrganism() {}
    
    		// Move constructor
    		UniqueOrganism(UniqueOrganism &object){
    			unique_organism = std::move(object.unique_organism);
    		}
    	};
    
    	std::vector<std::vector<UniqueOrganism>> cell_grid;
    
    public:
    	World() {
    		cell_grid = std::vector<std::vector<UniqueOrganism>> (20, std::vector<UniqueOrganism>(20, nullptr));
    	}
    	~World() {}
    
    };
    I know there is no copy/assign with unique_ptr. There is also no copy constructor with unique_ptr and that unique_ptr owns the object without reference counting. What is lacking in my understanding?

    What I am uncertain of is unique_ptr can reside within a container. Because copy/assign is not supported, I chose to embed the unique_ptr inside a class

  2. #2
    Registered User
    Join Date
    May 2010
    Posts
    178
    I tried rearranging my code:

    Code:
    class World{
    
    	struct UniqueOrganism{
    		std::unique_ptr<Organism> unique_organism;
    		
    		UniqueOrganism() {}
    
    		// Move constructor
    		UniqueOrganism(UniqueOrganism &object){
    			unique_organism = std::move(object.unique_organism);
    		}
    	};
    
    	std::vector<std::vector<UniqueOrganism>> cell_grid;
    public:
    	World() : cell_grid(20, std::vector<UniqueOrganism>(20)) {}
    	~World() {}
    };
    and received familiar errors related to trying to invoke the private copy constructor on initialization of cell_grid:

    Code:
    1>c:\users\comp sci\documents\visual studio 2010\projects\predatorpreysimulation\predatorpreysimulation\world.h(20): error C2248: 'std::unique_ptr<_Ty>::operator =' : cannot access private member declared in class 'std::unique_ptr<_Ty>'
    1>          with
    1>          [
    1>              _Ty=Organism
    1>          ]
    1>          c:\microsoft visual studio 10.0\vc\include\memory(2352) : see declaration of 'std::unique_ptr<_Ty>::operator ='
    1>          with
    1>          [
    1>              _Ty=Organism
    1>          ]
    1>          This diagnostic occurred in the compiler generated function 'World::UniqueOrganism &World::UniqueOrganism::operator =(const World::UniqueOrganism &)'
    1>
    1>Build FAILED.

  3. #3
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    What you comment as a move constructor is a copy constructor instead. A move constructor would have an rvalue reference parameter.

    Quote Originally Posted by Imanuel
    What I am uncertain of is unique_ptr can reside within a container.
    The C++11 version of various standard containers allow for that.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  4. #4
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    While you can use move-only objects (such as unique_ptr) in containers, some methods of the containers have more extensive requirements, i.e. they require the element type to be copyable and not just movable.

    The (size_type n, E e) constructor of vector is one such. This should be fairly obvious: the constructor makes the vector n elements large and initializes each of these elements to be a copy of e. If E isn't copyable, that's not going to fly.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  5. #5
    Registered User
    Join Date
    May 2010
    Posts
    178
    Quote Originally Posted by CornedBee View Post
    While you can use move-only objects (such as unique_ptr) in containers, some methods of the containers have more extensive requirements, i.e. they require the element type to be copyable and not just movable.

    The (size_type n, E e) constructor of vector is one such. This should be fairly obvious: the constructor makes the vector n elements large and initializes each of these elements to be a copy of e. If E isn't copyable, that's not going to fly.
    I actually already understood that ... the primary reason for my compile-time errors. My question was eliciting how to use a unique_ptr inside a container when every container has a copy constructor which violates unique_ptr no copy/no assignment?

  6. #6
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    You don't necessarily need to avoid STL containers, it is only that for once you will have to pay attention to avoid operations that make copies.

    I am certain that a vector can be default constructed and then you can push_back as many unique pointers as you want.

  7. #7
    Registered User
    Join Date
    May 2010
    Posts
    178
    Quote Originally Posted by whiteflags View Post
    You don't necessarily need to avoid STL containers, it is only that for once you will have to pay attention to avoid operations that make copies.

    I am certain that a vector can be default constructed and then you can push_back as many unique pointers as you want.
    Can you provide a complete example?

  8. #8
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    I can, but I won't.

    vector::vector - C++ Reference
    Pay attention to the demonstration of vector's constructors on this page and recognize that one of them is the default one.

    vector::push_back - C++ Reference
    Recognize that the C++11 version of this function uses move semantics.

    Welcome to the wonderful world of reading.
    Last edited by whiteflags; 01-26-2013 at 05:43 PM.

  9. #9
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Quote Originally Posted by Imanuel View Post
    I actually already understood that ... the primary reason for my compile-time errors. My question was eliciting how to use a unique_ptr inside a container when every container has a copy constructor which violates unique_ptr no copy/no assignment?
    As long as you don't instantiate the container's copy constructor (i.e. never try to copy the container), that doesn't matter.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. std::unique_ptr/shared_ptr assignment semantics
    By Elkvis in forum C++ Programming
    Replies: 3
    Last Post: 08-06-2012, 11:25 AM
  2. std::unique_ptr
    By KIBO in forum C++ Programming
    Replies: 4
    Last Post: 12-07-2010, 07:48 AM
  3. Left Brain v Right Brain
    By stevesmithx in forum A Brief History of Cprogramming.com
    Replies: 8
    Last Post: 10-30-2008, 09:13 AM
  4. Best way to pick up C?
    By Ninestar in forum C Programming
    Replies: 4
    Last Post: 02-17-2006, 11:11 AM
  5. brain vs. computer (brain wins hands down)
    By hk_mp5kpdw in forum A Brief History of Cprogramming.com
    Replies: 18
    Last Post: 09-17-2003, 08:41 PM