Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't make_unique work with unique_ptr::reset?

I tried compiling some C++ code with VS2013, and unique_ptr::reset() doesn't seem to work with make_unique(); a small compilable repro code snippet follows:

#include <memory>
using namespace std;

int main() {
    unique_ptr<int[]> p = make_unique<int[]>(3);
    p.reset(make_unique<int[]>(10));    
}

Compiling from command-line:

C:\Temp\CppTests>cl /EHsc /W4 /nologo test.cpp

These are the errors from the MSVC compiler:

test.cpp(6) : error C2280: 'void std::unique_ptr<int [],std::default_delete<_Ty>
>::reset<std::unique_ptr<_Ty,std::default_delete<_Ty>>>(_Ptr2)' : attempting to
reference a deleted function
        with
        [
            _Ty=int []
,            _Ptr2=std::unique_ptr<int [],std::default_delete<int []>>
        ]
        C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\INCLUDE\memory(16
23) : see declaration of 'std::unique_ptr<int [],std::default_delete<_Ty>>::rese
t'
        with
        [
            _Ty=int []
        ]

However, the following code seems to compile fine:

p = make_unique<int[]>(10);

What is the reason of this behavior? Why does unique_ptr::operator=() work with make_unique(), but unique_ptr::reset() doesn't?

like image 939
Mr.C64 Avatar asked Apr 01 '14 21:04

Mr.C64


People also ask

What does unique_ptr reset method do?

unique_ptr::resetReplaces the managed object. 1) Given current_ptr , the pointer that was managed by *this, performs the following actions, in this order: Saves a copy of the current pointer old_ptr = current_ptr. Overwrites the current pointer with the argument current_ptr = ptr.

What happens to unique_ptr after move?

"Moving" transfers ownership to a new unique_ptr and resets the old unique_ptr .

Does unique_ptr call Delete?

An explicit delete for a unique_ptr would be reset() . But do remember that unique_ptr are there so that you don't have to manage directly the memory they hold. That is, you should know that a unique_ptr will safely delete its underlying raw pointer once it goes out of scope.

What is std :: Make_unique?

std::make_uniqueConstructs an object of type T and wraps it in a std::unique_ptr. 1) Constructs a non-array type T . The arguments args are passed to the constructor of T . The function does not participate in the overload resolution if T is an array type.


1 Answers

reset() takes a pointer.

What you seem to want is simple move assignment:

#include <memory>
using namespace std;

int main() {
    unique_ptr<int[]> p = make_unique<int[]>(3);
    p = make_unique<int[]>(10);    
}

some compilers might still like you to specify the std::move() there, but it's not strictly required.

like image 162
sehe Avatar answered Sep 22 '22 16:09

sehe