Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use unique_ptr with std::copy?

I googled and found nothing. I guess I just don't know how to type the right question.

Okay, my simple MemoryBlock class has two member data, int size and int* data. So to build a copy constructor, I use std::copy to do the memory copy. Now I would like to try the C++ smart pointer to replace the raw pointer. Say using the unique_ptr<int> data. What is the equivalence of the following code? Because now, rhs.data + size won't work.

std::copy(rhs.data, rhs.data + size, data);
like image 715
Daniel Avatar asked Jan 12 '17 15:01

Daniel


People also ask

Can unique_ptr be copied?

A unique_ptr does not share its pointer. It cannot be copied to another unique_ptr , passed by value to a function, or used in any C++ Standard Library algorithm that requires copies to be made. A unique_ptr can only be moved.

Can you pass a std :: unique_ptr as a parameter to a function?

You cannot do that because unique_ptr has a move constructor but not a copy constructor. According to the standard, when a move constructor is defined but a copy constructor is not defined, the copy constructor is deleted.

How is unique_ptr implemented in C++?

I have following C++ code snippet, which implements a unique pointer logic: template<typename T> class unique_ptr { private: T* _ptr; public: unique_ptr(T& t) { _ptr = &t; } unique_ptr(unique_ptr<T>&& uptr) { _ptr = std::move(uptr. _ptr); uptr.

Can you assign a unique_ptr?

This means that a unique_ptr can be assigned to the unique_ptr returned from a function, but you can't assign one declared unique_ptr to another. But if you invoke a move assignment (with std::move) you can assign them, but the lhs unique_ptr now owns the object and the rhs now owns nothing.


2 Answers

First of all you have to allocate the array for the created object and then you can copy values to it. For example

MemoryBlock( const MemoryBlock &m ) : size( m.size ), data( new int[m.size] )
{
    std::copy(m.data.get(), m.data.get() + m.size, data.get());
}

Take into account that the member data data must be declared like

std::unique_ptr<int[]> data;

If you want to add the move constructor to the class you can define it the following way

MemoryBlock( MemoryBlock &&m ) : size( 0 ), data( nullptr )
{
    std::swap( m.size, size );
    std::swap( m.data, data );
}
like image 73
Vlad from Moscow Avatar answered Sep 21 '22 22:09

Vlad from Moscow


You can use the std::unique_ptr<>::get() function, that returns a pointer to the managed object or nullptr if no object is owned.

I.e.:

std::copy(rhs.data.get(), rhs.data.get() + size, data.get());

As also commented by NathanOliver, another option is to replace raw memory pointer owned by unique_ptr with std::vector altogether.

like image 34
roalz Avatar answered Sep 21 '22 22:09

roalz