This example compiles and runs well with gcc 4.8.3:
#include <memory>
#include <functional>
#include <iostream>
int main() {
auto str = new const char[6]{'h', 'e', 'l', 'l', 'o', '\0'};
std::unique_ptr<const char[], std::function<void(const char *)>> u_ptr(str, [](const char *s){ delete[] s; });
std::cout << u_ptr.get() << std::endl;
}
But when I try it with Visual Studio Professional 2013 it doesn't compile (complains about a deleted function). Is this not yet possible with Visual Studio 2013? Or is my sample code wrong and gcc ignores my mistake?
Error is:
main.cpp(8) : error C2280: 'std::unique_ptr>::unique_ptr>(_Ptr2,_Dx2)' : attempting to reference a deleted function with [ _Ptr2=const char * , _Dx2=main:: ] C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\INCLUDE\memory(16 16) : see declaration of 'std::unique_ptr>::unique_ptr'
unique_ptr objects automatically delete the object they manage (using a deleter) as soon as they themselves are destroyed, or as soon as their value changes either by an assignment operation or by an explicit call to unique_ptr::reset.
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.
unique_ptr. An unique_ptr has exclusive ownership of the object it points to and will destroy the object when the pointer goes out of scope.
A unique_ptr can only be moved. This means that the ownership of the memory resource is transferred to another unique_ptr and the original unique_ptr no longer owns it. We recommend that you restrict an object to one owner, because multiple ownership adds complexity to the program logic.
This appears to be a defect in the Visual C++ 2013 standard library. I cannot reproduce the problem on 2015.
The unique_ptr
class has this constructor for taking a pointer and a deleter:
unique_ptr(pointer _Ptr,
typename _If<is_reference<_Dx>::value, _Dx,
const typename remove_reference<_Dx>::type&>::type _Dt) _NOEXCEPT
: _Mybase(_Ptr, _Dt)
{ // construct with pointer and (maybe const) deleter&
}
However, the unique_ptr<T[]>
specialization also has a catch-all constructor:
template<class _Ptr2,
class _Dx2>
unique_ptr(_Ptr2, _Dx2) = delete;
This version is preferred over the previous one.
However, because the non-specialized unique_ptr
doesn't have it at all, changing u_ptr
to a const char
instead of const char[]
fixes the problem.
Using the array version with a deleter like you're doing is also unnecessary:
If you want to call delete[]
on your pointer, there's already a specialization for arrays. You don't need a custom deleter.
If you want to do something else, you should use the non-specialized version.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With