I don't ask about new operator
like here . Please, read question carefully.
I want to know why we need special function make_unique
over special constructor of unique_ptr.
unique_ptr
could use constructor like this to make make_unique
unneccessary:
template<typename T, typename ...TArgs>
unique_ptr::unique_ptr(TArgs&&... args)
: inner_ptr(new T(std::forward(args)...))
{}
There's a couple of reasons for this.
The first has to do with a bit of C++ history. Prior to C++17, there was no exception safety with the constructor, so doing the following:
some_func(std::unique_ptr<T1>(), std::unique_ptr<T2>())
would leak memory were the constructor for T1 to throw an exception, as the C++ standard did not require that, in this case the first unique_ptr, should have it's memory deallocated. This is no longer the case since C++17
Second, it allows for a more general rule of "never to use new
" which without make_unique
would be "never use new
except for when using unique_ptr
or shared_ptr
"
Also there's the added bonus of no redundant typing, as with the constructor you have to do:
auto p = std::unique_ptr<T>(new T());
listing T
twice, which can be particularly ugly in the case of long type names. With make_unique
this shortens to
auto p = std::make_unique<T>();
I want to summarize discussion with Some programmer dude , StoryTeller - Unslander Monica and Raymond Chen
So, there are 2 reasons:
std::make_unique
pairs well withstd::make_shared which was introduced earlier so this was easier to learn than new constructor for unique_ptr
. unique_ptr
and constructor of inner value type ( T
) if this type have own constructor which takes a pointer to self type. Egstruct Inner{
Inner() = default;
Inner(Inner* parent_node): parent(parent_node){}
Inner* parent = nullptr;
};
Inner* parent = make_parent();
// It would be not clear for human which constructor must be called here
std::unique_ptr<Inner> child(parent);
Compiler can deduce which constructor should be called here but it is hard for human. So having function std::make_unique
is beneficial because it is clear that all constructors of std::unique_ptr
create only unique_ptr and never call inner value constructor while std::make_unique
would always call constructor of inner value. This makes code much easier to reason about.
Thanks to everyone for discussion!
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.