It would be easier to read/write the second line of my example since the type of the template argument is obvious:
#include <memory>
struct Foo{};
int main()
{
// redundant: good
auto foo1 = std::unique_ptr<Foo>(new Foo());
// without explicitness: does not compile
auto foo2 = std::unique_ptr(new Foo());
}
Of course, if you want to use polymorphism, we could always write:
auto base = std::unique_ptr<Base>(new Derived());
What is the reason for such a constraint?
It can be assigned: class owner { std::unique_ptr<someObject> owned; public: owner() { owned=std::unique_ptr<someObject>(new someObject()); } };
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.
std::unique_ptr is a smart pointer that owns and manages another object through a pointer and disposes of that object when the unique_ptr goes out of scope. The object is disposed of, using the associated deleter when either of the following happens: the managing unique_ptr object is destroyed.
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.
You can, of course, use std::unique_ptr as a composition member of your class. This way, you don’t have to worry about ensuring your class destructor deletes the dynamic memory, as the std::unique_ptr will be automatically destroyed when the class object is destroyed.
We can not assign a std::unique_ptr object to another smart pointer. std::unique_ptr disposes the managed object when the unique_ptr goes out of context or is assigned with nullptr. It takes care of the common mistake that programmers make of forgetting to delete dynamically allocated objects.
std::unique_ptr is the C++11 replacement for std::auto_ptr. It should be used to manage any dynamically allocated object that is not shared by multiple objects.
If T is a derived class of some base B, then std::unique_ptr<T> is implicitly convertible to std::unique_ptr<B>. The default deleter of the resulting std::unique_ptr<B> will use operator delete for B, leading to undefined behavior unless the destructor of B is virtual.
This is not an issue that's... unique to std::unique_ptr
- instantiation of template classes does not automatically deduce the types from the constructors previous to C++17. This is why facilities such as std::make_unique
, std::make_pair
and std::make_tuple
exist: they use template function argument deduction to reduce boilerplate.
In C++17 you will be able to write:
auto foo2 = std::unique_ptr(new Foo());
thanks to class template deduction - assuming P0433R0 is accepted, which adds a deduction guide to std::unique_ptr
.
The deduction guide is required because std::unique_ptr
's constructor that takes a raw pointer uses the pointer
type alias which is defined as follows:
std::remove_reference<Deleter>::type::pointer
if that type exists, otherwiseT*
. Must satisfyNullablePointer
.
Type aliases like pointer
are non-deducible contexts, so P0433R0 proposes the addition of:
template<class T> unique_ptr(T*)
-> unique_ptr<T, default_delete<T>>;
template<class T, class V> unique_ptr(T*, V)
-> unique_ptr<T, default_delete<T, V>>;
template<class U, class V> unique_ptr(U, V)
-> unique_ptr<typename pointer_traits<typename V::pointer>::element_type, V>;
Which would enable class template deduction for std::unique_ptr
.
The real reason for the absense of the deduction guides is this:
There is no class template argument deduction from pointer type because it is impossible to distinguish a pointer obtained from array and non-array forms of new
Side note: The other answer promised that c++17 will allow this to compile:
This is simply not the case. Also For the above reason.
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