[util.smartptr.shared.io] in the C++11 standard mandates an operator<<
for
shared_ptr
s:
template<class E, class T, class Y>
basic_ostream<E, T>& operator<< (basic_ostream<E, T>& os, shared_ptr<Y> const& p);
However unless I'm missing it, I see nothing similar in [unique.ptr], and the reference on en.cppreference.com agrees. Is there a reason for the difference?
(since C++11) 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.
The unique_ptr shall not be empty (i.e., its stored pointer shall not be a null pointer) in order to be dereferenciable. This can easily be checked by casting the unique_ptr object to bool (see unique_ptr::operator bool). It is equivalent to: *get().
std::unique_ptr::unique_ptr The object is empty (owns nothing), with value-initialized stored pointer and stored deleter. construct from pointer (3) The object takes ownership of p, initializing its stored pointer to p and value-initializing its stored deleter.
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.
In general, you should not return std::unique_ptr by pointer (ever) or reference (unless you have a specific compelling reason to). If you want the function to take ownership of the contents of the pointer, pass the std::unique_ptr by value.
(2) (since C++11) 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.
Unlike std::shared_ptr, std::unique_ptr may manage an object through any custom handle type that satisfies NullablePointer. This allows, for example, managing objects located in shared memory, by supplying a Deleter that defines typedef boost::offset_ptr pointer; or another fancy pointer .
Note that unique_ptr 's assignment operator only accepts rvalues, which are typically generated by std::move. (The unique_ptr class explicitly deletes its lvalue copy constructor and lvalue assignment operator.) Foo 1 Creating new Foo...
Is there a reason for the difference?
No, there isn't. Just as with make_unique
this is an "oversight" and should be added in future (if someone can be bothered to send a proposal).
In the meantime you can output ptr.get()
instead, or - if not afraid of undefined behavior:
#if __cplusplus <= 201600 // Some time in future
namespace std {
template <class E, class T, class Y, class D>
basic_ostream<E, T>& operator<< (basic_ostream<E, T>& os,
unique_ptr<Y, D> const& p) {
return os << p.get();
}
}
#endif
That is undefined according to [namespace.std]:
The behavior of a C++ program is undefined if it adds declarations or definitions to namespace
std
[…] unless otherwise specified.
... and the above is not specifically allowed for this matter. However, this kind of undefined behavior is fine and can be invoked without any impacts whatsoever.
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