Why use std::make_unique in C++17?
As far as I understand, C++14 introduced std::make_unique
because, as a result of the parameter evaluation order not being specified, this was unsafe:
f(std::unique_ptr<MyClass>(new MyClass(param)), g()); // Syntax A
(Explanation: if the evaluation first allocates the memory for the raw pointer, then calls g()
and an exception is thrown before the std::unique_ptr
construction, then the memory is leaked.)
Calling std::make_unique
was a way to constrain the call order, thus making things safe:
f(std::make_unique<MyClass>(param), g()); // Syntax B
Since then, C++17 has clarified the evaluation order, making Syntax A safe too, so here's my question: is there still a reason to use std::make_unique
over std::unique_ptr
's constructor in C++17? Can you give some examples?
As of now, the only reason I can imagine is that it allows to type MyClass
only once (assuming you don't need to rely on polymorphism with std::unique_ptr<Base>(new Derived(param))
). However, that seems like a pretty weak reason, especially when std::make_unique
doesn't allow to specify a deleter while std::unique_ptr
's constructor does.
And just to be clear, I'm not advocating in favor of removing std::make_unique
from the Standard Library (keeping it makes sense at least for backward compatibility), but rather wondering if there are still situations in which it is strongly preferred to std::unique_ptr
c++ c++17 unique-ptr
|
show 1 more comment
As far as I understand, C++14 introduced std::make_unique
because, as a result of the parameter evaluation order not being specified, this was unsafe:
f(std::unique_ptr<MyClass>(new MyClass(param)), g()); // Syntax A
(Explanation: if the evaluation first allocates the memory for the raw pointer, then calls g()
and an exception is thrown before the std::unique_ptr
construction, then the memory is leaked.)
Calling std::make_unique
was a way to constrain the call order, thus making things safe:
f(std::make_unique<MyClass>(param), g()); // Syntax B
Since then, C++17 has clarified the evaluation order, making Syntax A safe too, so here's my question: is there still a reason to use std::make_unique
over std::unique_ptr
's constructor in C++17? Can you give some examples?
As of now, the only reason I can imagine is that it allows to type MyClass
only once (assuming you don't need to rely on polymorphism with std::unique_ptr<Base>(new Derived(param))
). However, that seems like a pretty weak reason, especially when std::make_unique
doesn't allow to specify a deleter while std::unique_ptr
's constructor does.
And just to be clear, I'm not advocating in favor of removing std::make_unique
from the Standard Library (keeping it makes sense at least for backward compatibility), but rather wondering if there are still situations in which it is strongly preferred to std::unique_ptr
c++ c++17 unique-ptr
4
However, that seems like a pretty weak reason --> Why it's a weak reason? It effectively reduces code duplication of type. As for the deleter, how often you are using a custom deleter when you usestd::unique_ptr
? It's not a argument to againstmake_unique
– liliscent
Dec 20 at 14:34
1
I say it's a weak reason because if there was nostd::make_unique
in the first place, I don't think that would be reason enough to add it to the STL, especially when it's a syntax which is less expressive than using the constructor, not more
– Eternal
Dec 20 at 15:26
1
If you have a program, created in c++14, using make_unique, you do not want the function to get removed from stl. Or if you want it to be backwards compatible.
– Serge
Dec 20 at 15:31
2
@Serge That's a good point, but it's a bit besides the object of my question. I'll make an edit to make it clearer
– Eternal
Dec 20 at 15:44
1
@Eternal please stop refering to C++ Standard Library as STL as it is incorrect and creates confusion. See stackoverflow.com/questions/5205491/…
– Marandil
Dec 21 at 10:37
|
show 1 more comment
As far as I understand, C++14 introduced std::make_unique
because, as a result of the parameter evaluation order not being specified, this was unsafe:
f(std::unique_ptr<MyClass>(new MyClass(param)), g()); // Syntax A
(Explanation: if the evaluation first allocates the memory for the raw pointer, then calls g()
and an exception is thrown before the std::unique_ptr
construction, then the memory is leaked.)
Calling std::make_unique
was a way to constrain the call order, thus making things safe:
f(std::make_unique<MyClass>(param), g()); // Syntax B
Since then, C++17 has clarified the evaluation order, making Syntax A safe too, so here's my question: is there still a reason to use std::make_unique
over std::unique_ptr
's constructor in C++17? Can you give some examples?
As of now, the only reason I can imagine is that it allows to type MyClass
only once (assuming you don't need to rely on polymorphism with std::unique_ptr<Base>(new Derived(param))
). However, that seems like a pretty weak reason, especially when std::make_unique
doesn't allow to specify a deleter while std::unique_ptr
's constructor does.
And just to be clear, I'm not advocating in favor of removing std::make_unique
from the Standard Library (keeping it makes sense at least for backward compatibility), but rather wondering if there are still situations in which it is strongly preferred to std::unique_ptr
c++ c++17 unique-ptr
As far as I understand, C++14 introduced std::make_unique
because, as a result of the parameter evaluation order not being specified, this was unsafe:
f(std::unique_ptr<MyClass>(new MyClass(param)), g()); // Syntax A
(Explanation: if the evaluation first allocates the memory for the raw pointer, then calls g()
and an exception is thrown before the std::unique_ptr
construction, then the memory is leaked.)
Calling std::make_unique
was a way to constrain the call order, thus making things safe:
f(std::make_unique<MyClass>(param), g()); // Syntax B
Since then, C++17 has clarified the evaluation order, making Syntax A safe too, so here's my question: is there still a reason to use std::make_unique
over std::unique_ptr
's constructor in C++17? Can you give some examples?
As of now, the only reason I can imagine is that it allows to type MyClass
only once (assuming you don't need to rely on polymorphism with std::unique_ptr<Base>(new Derived(param))
). However, that seems like a pretty weak reason, especially when std::make_unique
doesn't allow to specify a deleter while std::unique_ptr
's constructor does.
And just to be clear, I'm not advocating in favor of removing std::make_unique
from the Standard Library (keeping it makes sense at least for backward compatibility), but rather wondering if there are still situations in which it is strongly preferred to std::unique_ptr
c++ c++17 unique-ptr
c++ c++17 unique-ptr
edited Dec 23 at 19:53
Peter Mortensen
13.5k1983111
13.5k1983111
asked Dec 20 at 14:23
Eternal
818815
818815
4
However, that seems like a pretty weak reason --> Why it's a weak reason? It effectively reduces code duplication of type. As for the deleter, how often you are using a custom deleter when you usestd::unique_ptr
? It's not a argument to againstmake_unique
– liliscent
Dec 20 at 14:34
1
I say it's a weak reason because if there was nostd::make_unique
in the first place, I don't think that would be reason enough to add it to the STL, especially when it's a syntax which is less expressive than using the constructor, not more
– Eternal
Dec 20 at 15:26
1
If you have a program, created in c++14, using make_unique, you do not want the function to get removed from stl. Or if you want it to be backwards compatible.
– Serge
Dec 20 at 15:31
2
@Serge That's a good point, but it's a bit besides the object of my question. I'll make an edit to make it clearer
– Eternal
Dec 20 at 15:44
1
@Eternal please stop refering to C++ Standard Library as STL as it is incorrect and creates confusion. See stackoverflow.com/questions/5205491/…
– Marandil
Dec 21 at 10:37
|
show 1 more comment
4
However, that seems like a pretty weak reason --> Why it's a weak reason? It effectively reduces code duplication of type. As for the deleter, how often you are using a custom deleter when you usestd::unique_ptr
? It's not a argument to againstmake_unique
– liliscent
Dec 20 at 14:34
1
I say it's a weak reason because if there was nostd::make_unique
in the first place, I don't think that would be reason enough to add it to the STL, especially when it's a syntax which is less expressive than using the constructor, not more
– Eternal
Dec 20 at 15:26
1
If you have a program, created in c++14, using make_unique, you do not want the function to get removed from stl. Or if you want it to be backwards compatible.
– Serge
Dec 20 at 15:31
2
@Serge That's a good point, but it's a bit besides the object of my question. I'll make an edit to make it clearer
– Eternal
Dec 20 at 15:44
1
@Eternal please stop refering to C++ Standard Library as STL as it is incorrect and creates confusion. See stackoverflow.com/questions/5205491/…
– Marandil
Dec 21 at 10:37
4
4
However, that seems like a pretty weak reason --> Why it's a weak reason? It effectively reduces code duplication of type. As for the deleter, how often you are using a custom deleter when you use
std::unique_ptr
? It's not a argument to against make_unique
– liliscent
Dec 20 at 14:34
However, that seems like a pretty weak reason --> Why it's a weak reason? It effectively reduces code duplication of type. As for the deleter, how often you are using a custom deleter when you use
std::unique_ptr
? It's not a argument to against make_unique
– liliscent
Dec 20 at 14:34
1
1
I say it's a weak reason because if there was no
std::make_unique
in the first place, I don't think that would be reason enough to add it to the STL, especially when it's a syntax which is less expressive than using the constructor, not more– Eternal
Dec 20 at 15:26
I say it's a weak reason because if there was no
std::make_unique
in the first place, I don't think that would be reason enough to add it to the STL, especially when it's a syntax which is less expressive than using the constructor, not more– Eternal
Dec 20 at 15:26
1
1
If you have a program, created in c++14, using make_unique, you do not want the function to get removed from stl. Or if you want it to be backwards compatible.
– Serge
Dec 20 at 15:31
If you have a program, created in c++14, using make_unique, you do not want the function to get removed from stl. Or if you want it to be backwards compatible.
– Serge
Dec 20 at 15:31
2
2
@Serge That's a good point, but it's a bit besides the object of my question. I'll make an edit to make it clearer
– Eternal
Dec 20 at 15:44
@Serge That's a good point, but it's a bit besides the object of my question. I'll make an edit to make it clearer
– Eternal
Dec 20 at 15:44
1
1
@Eternal please stop refering to C++ Standard Library as STL as it is incorrect and creates confusion. See stackoverflow.com/questions/5205491/…
– Marandil
Dec 21 at 10:37
@Eternal please stop refering to C++ Standard Library as STL as it is incorrect and creates confusion. See stackoverflow.com/questions/5205491/…
– Marandil
Dec 21 at 10:37
|
show 1 more comment
4 Answers
4
active
oldest
votes
You're right that the main reason was removed. There are still the don't use new guidelines and that it is less typing reasons (don't have to repeat the type or use the word new
). Admittedly those aren't strong arguments but I really like not seeing new
in my code.
Also don't forget about consistency. You absolutely should be using make_shared
so using make_unique
is natural and fits the pattern. It's then trivial to change std::make_unique<MyClass>(param)
to std::make_shared<MyClass>(param)
(or the reverse) where the syntax A requires much more of a rewrite.
Why do you like not seeing "new" in code?
– reggaeguitar
Dec 20 at 23:35
29
@reggaeguitar If I see anew
I need to stop and think: how long is this pointer going to live? Did I handle it correctly? If there is an exception, is everything cleaned up correctly? I'd like to not ask myself those questions and waste my time on it and if I don't usenew
, I don't have to ask those questions.
– NathanOliver
Dec 20 at 23:39
3
Imagine you do a grep over all the source files of your project and don't find a singlenew
. Wouldn't this be wonderful?
– Sebastian Mach
Dec 21 at 9:26
@SebastianMach: well, of course you'd still get some placement new...
– Matthieu M.
Dec 22 at 12:06
The main advantage of the "don't use new" guideline it that it's simple, so it's an easy guideline to give to the less experienced developers you may be working with. I hadn't realized at first, but that has value in and of itself
– Eternal
Dec 22 at 12:43
add a comment |
make_unique
distinguishes T
from T
and T[N]
, unique_ptr(new ...)
does not.
You can easily get undefined behaviour (UB) by passing a pointer that was new
ed to a unique_ptr<T>
, or by passing a pointer that was new
ed to a unique_ptr<T>
.
add a comment |
The reason is to have shorter code without duplicates. Compare
f(std::unique_ptr<MyClass>(new MyClass(param)), g());
f(std::make_unique<MyClass>(param), g());
You save MyClass
, new
and braces. It costs only one character more in make in comparison with ptr.
2
Well, as I said in the question, I can see it's less typing with only one mention ofMyClass
, but I was wondering if there was a stronger reason to use it
– Eternal
Dec 20 at 15:37
2
In many cases deduction guide would help to eliminate the<MyClass>
part in the first variant.
– AnT
Dec 20 at 15:52
7
It's already been said in the comments for other answers, but while c++17 introduced template type deduction for constructors, in the case ofstd::unique_ptr
it's disallowed. It has to do with distinguishingstd::unique_ptr<T>
andstd::unique_ptr<T>
– Eternal
Dec 20 at 17:53
add a comment |
Every use of new
has to be extra carefully audited for lifetime correctness; does it get deleted? Only once?
Every use of make_unique
doesn't for those extra characteristics; so long as the owning object has "correct" lifetime, it recursively makes the unique pointer have "correct".
Now, it is true that unique_ptr<Foo>(new Foo())
is identical in all ways1 to make_unique<Foo>()
; it just requires a simpler "grep your source code for all uses of new
to audit them".
1 actually a lie in the general case. Perfect forwarding isn't perfect, {}
, default init, arrays are all exceptions.
Technicallyunique_ptr<Foo>(new Foo)
isn't quite identical tomake_unique<Foo>()
... the latter doesnew Foo()
But otherwise, yes.
– Barry
Dec 20 at 15:57
@barry true, overloaded operator new is possible.
– Yakk - Adam Nevraumont
Dec 20 at 16:38
@dedup what foul C++17 witchcraft is that?
– Yakk - Adam Nevraumont
Dec 20 at 16:53
2
@Deduplicator while c++17 introduced template type deduction for constructors, in the case ofstd::unique_ptr
it's disallowed. If has to do with distinguishingstd::unique_ptr<T>
andstd::unique_ptr<T>
– Eternal
Dec 20 at 17:02
@Yakk-AdamNevraumont I didn't mean overloading new, I just meant default-init vs value-init.
– Barry
Dec 20 at 17:43
|
show 1 more comment
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53870522%2fwhy-use-stdmake-unique-in-c17%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
4 Answers
4
active
oldest
votes
4 Answers
4
active
oldest
votes
active
oldest
votes
active
oldest
votes
You're right that the main reason was removed. There are still the don't use new guidelines and that it is less typing reasons (don't have to repeat the type or use the word new
). Admittedly those aren't strong arguments but I really like not seeing new
in my code.
Also don't forget about consistency. You absolutely should be using make_shared
so using make_unique
is natural and fits the pattern. It's then trivial to change std::make_unique<MyClass>(param)
to std::make_shared<MyClass>(param)
(or the reverse) where the syntax A requires much more of a rewrite.
Why do you like not seeing "new" in code?
– reggaeguitar
Dec 20 at 23:35
29
@reggaeguitar If I see anew
I need to stop and think: how long is this pointer going to live? Did I handle it correctly? If there is an exception, is everything cleaned up correctly? I'd like to not ask myself those questions and waste my time on it and if I don't usenew
, I don't have to ask those questions.
– NathanOliver
Dec 20 at 23:39
3
Imagine you do a grep over all the source files of your project and don't find a singlenew
. Wouldn't this be wonderful?
– Sebastian Mach
Dec 21 at 9:26
@SebastianMach: well, of course you'd still get some placement new...
– Matthieu M.
Dec 22 at 12:06
The main advantage of the "don't use new" guideline it that it's simple, so it's an easy guideline to give to the less experienced developers you may be working with. I hadn't realized at first, but that has value in and of itself
– Eternal
Dec 22 at 12:43
add a comment |
You're right that the main reason was removed. There are still the don't use new guidelines and that it is less typing reasons (don't have to repeat the type or use the word new
). Admittedly those aren't strong arguments but I really like not seeing new
in my code.
Also don't forget about consistency. You absolutely should be using make_shared
so using make_unique
is natural and fits the pattern. It's then trivial to change std::make_unique<MyClass>(param)
to std::make_shared<MyClass>(param)
(or the reverse) where the syntax A requires much more of a rewrite.
Why do you like not seeing "new" in code?
– reggaeguitar
Dec 20 at 23:35
29
@reggaeguitar If I see anew
I need to stop and think: how long is this pointer going to live? Did I handle it correctly? If there is an exception, is everything cleaned up correctly? I'd like to not ask myself those questions and waste my time on it and if I don't usenew
, I don't have to ask those questions.
– NathanOliver
Dec 20 at 23:39
3
Imagine you do a grep over all the source files of your project and don't find a singlenew
. Wouldn't this be wonderful?
– Sebastian Mach
Dec 21 at 9:26
@SebastianMach: well, of course you'd still get some placement new...
– Matthieu M.
Dec 22 at 12:06
The main advantage of the "don't use new" guideline it that it's simple, so it's an easy guideline to give to the less experienced developers you may be working with. I hadn't realized at first, but that has value in and of itself
– Eternal
Dec 22 at 12:43
add a comment |
You're right that the main reason was removed. There are still the don't use new guidelines and that it is less typing reasons (don't have to repeat the type or use the word new
). Admittedly those aren't strong arguments but I really like not seeing new
in my code.
Also don't forget about consistency. You absolutely should be using make_shared
so using make_unique
is natural and fits the pattern. It's then trivial to change std::make_unique<MyClass>(param)
to std::make_shared<MyClass>(param)
(or the reverse) where the syntax A requires much more of a rewrite.
You're right that the main reason was removed. There are still the don't use new guidelines and that it is less typing reasons (don't have to repeat the type or use the word new
). Admittedly those aren't strong arguments but I really like not seeing new
in my code.
Also don't forget about consistency. You absolutely should be using make_shared
so using make_unique
is natural and fits the pattern. It's then trivial to change std::make_unique<MyClass>(param)
to std::make_shared<MyClass>(param)
(or the reverse) where the syntax A requires much more of a rewrite.
answered Dec 20 at 14:47
NathanOliver
86.7k15120180
86.7k15120180
Why do you like not seeing "new" in code?
– reggaeguitar
Dec 20 at 23:35
29
@reggaeguitar If I see anew
I need to stop and think: how long is this pointer going to live? Did I handle it correctly? If there is an exception, is everything cleaned up correctly? I'd like to not ask myself those questions and waste my time on it and if I don't usenew
, I don't have to ask those questions.
– NathanOliver
Dec 20 at 23:39
3
Imagine you do a grep over all the source files of your project and don't find a singlenew
. Wouldn't this be wonderful?
– Sebastian Mach
Dec 21 at 9:26
@SebastianMach: well, of course you'd still get some placement new...
– Matthieu M.
Dec 22 at 12:06
The main advantage of the "don't use new" guideline it that it's simple, so it's an easy guideline to give to the less experienced developers you may be working with. I hadn't realized at first, but that has value in and of itself
– Eternal
Dec 22 at 12:43
add a comment |
Why do you like not seeing "new" in code?
– reggaeguitar
Dec 20 at 23:35
29
@reggaeguitar If I see anew
I need to stop and think: how long is this pointer going to live? Did I handle it correctly? If there is an exception, is everything cleaned up correctly? I'd like to not ask myself those questions and waste my time on it and if I don't usenew
, I don't have to ask those questions.
– NathanOliver
Dec 20 at 23:39
3
Imagine you do a grep over all the source files of your project and don't find a singlenew
. Wouldn't this be wonderful?
– Sebastian Mach
Dec 21 at 9:26
@SebastianMach: well, of course you'd still get some placement new...
– Matthieu M.
Dec 22 at 12:06
The main advantage of the "don't use new" guideline it that it's simple, so it's an easy guideline to give to the less experienced developers you may be working with. I hadn't realized at first, but that has value in and of itself
– Eternal
Dec 22 at 12:43
Why do you like not seeing "new" in code?
– reggaeguitar
Dec 20 at 23:35
Why do you like not seeing "new" in code?
– reggaeguitar
Dec 20 at 23:35
29
29
@reggaeguitar If I see a
new
I need to stop and think: how long is this pointer going to live? Did I handle it correctly? If there is an exception, is everything cleaned up correctly? I'd like to not ask myself those questions and waste my time on it and if I don't use new
, I don't have to ask those questions.– NathanOliver
Dec 20 at 23:39
@reggaeguitar If I see a
new
I need to stop and think: how long is this pointer going to live? Did I handle it correctly? If there is an exception, is everything cleaned up correctly? I'd like to not ask myself those questions and waste my time on it and if I don't use new
, I don't have to ask those questions.– NathanOliver
Dec 20 at 23:39
3
3
Imagine you do a grep over all the source files of your project and don't find a single
new
. Wouldn't this be wonderful?– Sebastian Mach
Dec 21 at 9:26
Imagine you do a grep over all the source files of your project and don't find a single
new
. Wouldn't this be wonderful?– Sebastian Mach
Dec 21 at 9:26
@SebastianMach: well, of course you'd still get some placement new...
– Matthieu M.
Dec 22 at 12:06
@SebastianMach: well, of course you'd still get some placement new...
– Matthieu M.
Dec 22 at 12:06
The main advantage of the "don't use new" guideline it that it's simple, so it's an easy guideline to give to the less experienced developers you may be working with. I hadn't realized at first, but that has value in and of itself
– Eternal
Dec 22 at 12:43
The main advantage of the "don't use new" guideline it that it's simple, so it's an easy guideline to give to the less experienced developers you may be working with. I hadn't realized at first, but that has value in and of itself
– Eternal
Dec 22 at 12:43
add a comment |
make_unique
distinguishes T
from T
and T[N]
, unique_ptr(new ...)
does not.
You can easily get undefined behaviour (UB) by passing a pointer that was new
ed to a unique_ptr<T>
, or by passing a pointer that was new
ed to a unique_ptr<T>
.
add a comment |
make_unique
distinguishes T
from T
and T[N]
, unique_ptr(new ...)
does not.
You can easily get undefined behaviour (UB) by passing a pointer that was new
ed to a unique_ptr<T>
, or by passing a pointer that was new
ed to a unique_ptr<T>
.
add a comment |
make_unique
distinguishes T
from T
and T[N]
, unique_ptr(new ...)
does not.
You can easily get undefined behaviour (UB) by passing a pointer that was new
ed to a unique_ptr<T>
, or by passing a pointer that was new
ed to a unique_ptr<T>
.
make_unique
distinguishes T
from T
and T[N]
, unique_ptr(new ...)
does not.
You can easily get undefined behaviour (UB) by passing a pointer that was new
ed to a unique_ptr<T>
, or by passing a pointer that was new
ed to a unique_ptr<T>
.
edited Dec 23 at 19:55
Peter Mortensen
13.5k1983111
13.5k1983111
answered Dec 20 at 15:54
Caleth
16.5k22138
16.5k22138
add a comment |
add a comment |
The reason is to have shorter code without duplicates. Compare
f(std::unique_ptr<MyClass>(new MyClass(param)), g());
f(std::make_unique<MyClass>(param), g());
You save MyClass
, new
and braces. It costs only one character more in make in comparison with ptr.
2
Well, as I said in the question, I can see it's less typing with only one mention ofMyClass
, but I was wondering if there was a stronger reason to use it
– Eternal
Dec 20 at 15:37
2
In many cases deduction guide would help to eliminate the<MyClass>
part in the first variant.
– AnT
Dec 20 at 15:52
7
It's already been said in the comments for other answers, but while c++17 introduced template type deduction for constructors, in the case ofstd::unique_ptr
it's disallowed. It has to do with distinguishingstd::unique_ptr<T>
andstd::unique_ptr<T>
– Eternal
Dec 20 at 17:53
add a comment |
The reason is to have shorter code without duplicates. Compare
f(std::unique_ptr<MyClass>(new MyClass(param)), g());
f(std::make_unique<MyClass>(param), g());
You save MyClass
, new
and braces. It costs only one character more in make in comparison with ptr.
2
Well, as I said in the question, I can see it's less typing with only one mention ofMyClass
, but I was wondering if there was a stronger reason to use it
– Eternal
Dec 20 at 15:37
2
In many cases deduction guide would help to eliminate the<MyClass>
part in the first variant.
– AnT
Dec 20 at 15:52
7
It's already been said in the comments for other answers, but while c++17 introduced template type deduction for constructors, in the case ofstd::unique_ptr
it's disallowed. It has to do with distinguishingstd::unique_ptr<T>
andstd::unique_ptr<T>
– Eternal
Dec 20 at 17:53
add a comment |
The reason is to have shorter code without duplicates. Compare
f(std::unique_ptr<MyClass>(new MyClass(param)), g());
f(std::make_unique<MyClass>(param), g());
You save MyClass
, new
and braces. It costs only one character more in make in comparison with ptr.
The reason is to have shorter code without duplicates. Compare
f(std::unique_ptr<MyClass>(new MyClass(param)), g());
f(std::make_unique<MyClass>(param), g());
You save MyClass
, new
and braces. It costs only one character more in make in comparison with ptr.
edited Dec 21 at 6:39
Pharap
2,16712232
2,16712232
answered Dec 20 at 14:33
S.M.
5,82931526
5,82931526
2
Well, as I said in the question, I can see it's less typing with only one mention ofMyClass
, but I was wondering if there was a stronger reason to use it
– Eternal
Dec 20 at 15:37
2
In many cases deduction guide would help to eliminate the<MyClass>
part in the first variant.
– AnT
Dec 20 at 15:52
7
It's already been said in the comments for other answers, but while c++17 introduced template type deduction for constructors, in the case ofstd::unique_ptr
it's disallowed. It has to do with distinguishingstd::unique_ptr<T>
andstd::unique_ptr<T>
– Eternal
Dec 20 at 17:53
add a comment |
2
Well, as I said in the question, I can see it's less typing with only one mention ofMyClass
, but I was wondering if there was a stronger reason to use it
– Eternal
Dec 20 at 15:37
2
In many cases deduction guide would help to eliminate the<MyClass>
part in the first variant.
– AnT
Dec 20 at 15:52
7
It's already been said in the comments for other answers, but while c++17 introduced template type deduction for constructors, in the case ofstd::unique_ptr
it's disallowed. It has to do with distinguishingstd::unique_ptr<T>
andstd::unique_ptr<T>
– Eternal
Dec 20 at 17:53
2
2
Well, as I said in the question, I can see it's less typing with only one mention of
MyClass
, but I was wondering if there was a stronger reason to use it– Eternal
Dec 20 at 15:37
Well, as I said in the question, I can see it's less typing with only one mention of
MyClass
, but I was wondering if there was a stronger reason to use it– Eternal
Dec 20 at 15:37
2
2
In many cases deduction guide would help to eliminate the
<MyClass>
part in the first variant.– AnT
Dec 20 at 15:52
In many cases deduction guide would help to eliminate the
<MyClass>
part in the first variant.– AnT
Dec 20 at 15:52
7
7
It's already been said in the comments for other answers, but while c++17 introduced template type deduction for constructors, in the case of
std::unique_ptr
it's disallowed. It has to do with distinguishing std::unique_ptr<T>
and std::unique_ptr<T>
– Eternal
Dec 20 at 17:53
It's already been said in the comments for other answers, but while c++17 introduced template type deduction for constructors, in the case of
std::unique_ptr
it's disallowed. It has to do with distinguishing std::unique_ptr<T>
and std::unique_ptr<T>
– Eternal
Dec 20 at 17:53
add a comment |
Every use of new
has to be extra carefully audited for lifetime correctness; does it get deleted? Only once?
Every use of make_unique
doesn't for those extra characteristics; so long as the owning object has "correct" lifetime, it recursively makes the unique pointer have "correct".
Now, it is true that unique_ptr<Foo>(new Foo())
is identical in all ways1 to make_unique<Foo>()
; it just requires a simpler "grep your source code for all uses of new
to audit them".
1 actually a lie in the general case. Perfect forwarding isn't perfect, {}
, default init, arrays are all exceptions.
Technicallyunique_ptr<Foo>(new Foo)
isn't quite identical tomake_unique<Foo>()
... the latter doesnew Foo()
But otherwise, yes.
– Barry
Dec 20 at 15:57
@barry true, overloaded operator new is possible.
– Yakk - Adam Nevraumont
Dec 20 at 16:38
@dedup what foul C++17 witchcraft is that?
– Yakk - Adam Nevraumont
Dec 20 at 16:53
2
@Deduplicator while c++17 introduced template type deduction for constructors, in the case ofstd::unique_ptr
it's disallowed. If has to do with distinguishingstd::unique_ptr<T>
andstd::unique_ptr<T>
– Eternal
Dec 20 at 17:02
@Yakk-AdamNevraumont I didn't mean overloading new, I just meant default-init vs value-init.
– Barry
Dec 20 at 17:43
|
show 1 more comment
Every use of new
has to be extra carefully audited for lifetime correctness; does it get deleted? Only once?
Every use of make_unique
doesn't for those extra characteristics; so long as the owning object has "correct" lifetime, it recursively makes the unique pointer have "correct".
Now, it is true that unique_ptr<Foo>(new Foo())
is identical in all ways1 to make_unique<Foo>()
; it just requires a simpler "grep your source code for all uses of new
to audit them".
1 actually a lie in the general case. Perfect forwarding isn't perfect, {}
, default init, arrays are all exceptions.
Technicallyunique_ptr<Foo>(new Foo)
isn't quite identical tomake_unique<Foo>()
... the latter doesnew Foo()
But otherwise, yes.
– Barry
Dec 20 at 15:57
@barry true, overloaded operator new is possible.
– Yakk - Adam Nevraumont
Dec 20 at 16:38
@dedup what foul C++17 witchcraft is that?
– Yakk - Adam Nevraumont
Dec 20 at 16:53
2
@Deduplicator while c++17 introduced template type deduction for constructors, in the case ofstd::unique_ptr
it's disallowed. If has to do with distinguishingstd::unique_ptr<T>
andstd::unique_ptr<T>
– Eternal
Dec 20 at 17:02
@Yakk-AdamNevraumont I didn't mean overloading new, I just meant default-init vs value-init.
– Barry
Dec 20 at 17:43
|
show 1 more comment
Every use of new
has to be extra carefully audited for lifetime correctness; does it get deleted? Only once?
Every use of make_unique
doesn't for those extra characteristics; so long as the owning object has "correct" lifetime, it recursively makes the unique pointer have "correct".
Now, it is true that unique_ptr<Foo>(new Foo())
is identical in all ways1 to make_unique<Foo>()
; it just requires a simpler "grep your source code for all uses of new
to audit them".
1 actually a lie in the general case. Perfect forwarding isn't perfect, {}
, default init, arrays are all exceptions.
Every use of new
has to be extra carefully audited for lifetime correctness; does it get deleted? Only once?
Every use of make_unique
doesn't for those extra characteristics; so long as the owning object has "correct" lifetime, it recursively makes the unique pointer have "correct".
Now, it is true that unique_ptr<Foo>(new Foo())
is identical in all ways1 to make_unique<Foo>()
; it just requires a simpler "grep your source code for all uses of new
to audit them".
1 actually a lie in the general case. Perfect forwarding isn't perfect, {}
, default init, arrays are all exceptions.
edited Dec 20 at 18:34
NathanOliver
86.7k15120180
86.7k15120180
answered Dec 20 at 15:52
Yakk - Adam Nevraumont
182k19188371
182k19188371
Technicallyunique_ptr<Foo>(new Foo)
isn't quite identical tomake_unique<Foo>()
... the latter doesnew Foo()
But otherwise, yes.
– Barry
Dec 20 at 15:57
@barry true, overloaded operator new is possible.
– Yakk - Adam Nevraumont
Dec 20 at 16:38
@dedup what foul C++17 witchcraft is that?
– Yakk - Adam Nevraumont
Dec 20 at 16:53
2
@Deduplicator while c++17 introduced template type deduction for constructors, in the case ofstd::unique_ptr
it's disallowed. If has to do with distinguishingstd::unique_ptr<T>
andstd::unique_ptr<T>
– Eternal
Dec 20 at 17:02
@Yakk-AdamNevraumont I didn't mean overloading new, I just meant default-init vs value-init.
– Barry
Dec 20 at 17:43
|
show 1 more comment
Technicallyunique_ptr<Foo>(new Foo)
isn't quite identical tomake_unique<Foo>()
... the latter doesnew Foo()
But otherwise, yes.
– Barry
Dec 20 at 15:57
@barry true, overloaded operator new is possible.
– Yakk - Adam Nevraumont
Dec 20 at 16:38
@dedup what foul C++17 witchcraft is that?
– Yakk - Adam Nevraumont
Dec 20 at 16:53
2
@Deduplicator while c++17 introduced template type deduction for constructors, in the case ofstd::unique_ptr
it's disallowed. If has to do with distinguishingstd::unique_ptr<T>
andstd::unique_ptr<T>
– Eternal
Dec 20 at 17:02
@Yakk-AdamNevraumont I didn't mean overloading new, I just meant default-init vs value-init.
– Barry
Dec 20 at 17:43
Technically
unique_ptr<Foo>(new Foo)
isn't quite identical to make_unique<Foo>()
... the latter does new Foo()
But otherwise, yes.– Barry
Dec 20 at 15:57
Technically
unique_ptr<Foo>(new Foo)
isn't quite identical to make_unique<Foo>()
... the latter does new Foo()
But otherwise, yes.– Barry
Dec 20 at 15:57
@barry true, overloaded operator new is possible.
– Yakk - Adam Nevraumont
Dec 20 at 16:38
@barry true, overloaded operator new is possible.
– Yakk - Adam Nevraumont
Dec 20 at 16:38
@dedup what foul C++17 witchcraft is that?
– Yakk - Adam Nevraumont
Dec 20 at 16:53
@dedup what foul C++17 witchcraft is that?
– Yakk - Adam Nevraumont
Dec 20 at 16:53
2
2
@Deduplicator while c++17 introduced template type deduction for constructors, in the case of
std::unique_ptr
it's disallowed. If has to do with distinguishing std::unique_ptr<T>
and std::unique_ptr<T>
– Eternal
Dec 20 at 17:02
@Deduplicator while c++17 introduced template type deduction for constructors, in the case of
std::unique_ptr
it's disallowed. If has to do with distinguishing std::unique_ptr<T>
and std::unique_ptr<T>
– Eternal
Dec 20 at 17:02
@Yakk-AdamNevraumont I didn't mean overloading new, I just meant default-init vs value-init.
– Barry
Dec 20 at 17:43
@Yakk-AdamNevraumont I didn't mean overloading new, I just meant default-init vs value-init.
– Barry
Dec 20 at 17:43
|
show 1 more comment
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53870522%2fwhy-use-stdmake-unique-in-c17%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
4
However, that seems like a pretty weak reason --> Why it's a weak reason? It effectively reduces code duplication of type. As for the deleter, how often you are using a custom deleter when you use
std::unique_ptr
? It's not a argument to againstmake_unique
– liliscent
Dec 20 at 14:34
1
I say it's a weak reason because if there was no
std::make_unique
in the first place, I don't think that would be reason enough to add it to the STL, especially when it's a syntax which is less expressive than using the constructor, not more– Eternal
Dec 20 at 15:26
1
If you have a program, created in c++14, using make_unique, you do not want the function to get removed from stl. Or if you want it to be backwards compatible.
– Serge
Dec 20 at 15:31
2
@Serge That's a good point, but it's a bit besides the object of my question. I'll make an edit to make it clearer
– Eternal
Dec 20 at 15:44
1
@Eternal please stop refering to C++ Standard Library as STL as it is incorrect and creates confusion. See stackoverflow.com/questions/5205491/…
– Marandil
Dec 21 at 10:37