Why use std::make_unique in C++17?












77















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










share|improve this question




















  • 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

    – llllllllll
    Dec 20 '18 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 '18 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 '18 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 '18 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 '18 at 10:37
















77















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










share|improve this question




















  • 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

    – llllllllll
    Dec 20 '18 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 '18 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 '18 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 '18 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 '18 at 10:37














77












77








77


10






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










share|improve this question
















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






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Dec 23 '18 at 19:53









Peter Mortensen

13.7k1986113




13.7k1986113










asked Dec 20 '18 at 14:23









EternalEternal

949816




949816








  • 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

    – llllllllll
    Dec 20 '18 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 '18 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 '18 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 '18 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 '18 at 10:37














  • 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

    – llllllllll
    Dec 20 '18 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 '18 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 '18 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 '18 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 '18 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

– llllllllll
Dec 20 '18 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

– llllllllll
Dec 20 '18 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 '18 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 '18 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 '18 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 '18 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 '18 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 '18 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 '18 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 '18 at 10:37












4 Answers
4






active

oldest

votes


















60














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.






share|improve this answer
























  • Why do you like not seeing "new" in code?

    – reggaeguitar
    Dec 20 '18 at 23:35






  • 32





    @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 '18 at 23:39






  • 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 '18 at 9:26











  • @SebastianMach: well, of course you'd still get some placement new...

    – Matthieu M.
    Dec 22 '18 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 '18 at 12:43





















38














make_unique distinguishes T from T and T[N], unique_ptr(new ...) does not.



You can easily get undefined behaviour by passing a pointer that was newed to a unique_ptr<T>, or by passing a pointer that was newed to a unique_ptr<T>.






share|improve this answer

































    20














    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.






    share|improve this answer





















    • 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 '18 at 15:37






    • 2





      In many cases deduction guide would help to eliminate the <MyClass> part in the first variant.

      – AnT
      Dec 20 '18 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 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 '18 at 17:53



















    16














    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.






    share|improve this answer


























    • 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 '18 at 15:57











    • @barry true, overloaded operator new is possible.

      – Yakk - Adam Nevraumont
      Dec 20 '18 at 16:38











    • @dedup what foul C++17 witchcraft is that?

      – Yakk - Adam Nevraumont
      Dec 20 '18 at 16:53






    • 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 '18 at 17:02











    • @Yakk-AdamNevraumont I didn't mean overloading new, I just meant default-init vs value-init.

      – Barry
      Dec 20 '18 at 17:43











    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
    });


    }
    });














    draft saved

    draft discarded


















    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









    60














    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.






    share|improve this answer
























    • Why do you like not seeing "new" in code?

      – reggaeguitar
      Dec 20 '18 at 23:35






    • 32





      @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 '18 at 23:39






    • 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 '18 at 9:26











    • @SebastianMach: well, of course you'd still get some placement new...

      – Matthieu M.
      Dec 22 '18 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 '18 at 12:43


















    60














    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.






    share|improve this answer
























    • Why do you like not seeing "new" in code?

      – reggaeguitar
      Dec 20 '18 at 23:35






    • 32





      @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 '18 at 23:39






    • 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 '18 at 9:26











    • @SebastianMach: well, of course you'd still get some placement new...

      – Matthieu M.
      Dec 22 '18 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 '18 at 12:43
















    60












    60








    60







    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.






    share|improve this answer













    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.







    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Dec 20 '18 at 14:47









    NathanOliverNathanOliver

    94.6k16131202




    94.6k16131202













    • Why do you like not seeing "new" in code?

      – reggaeguitar
      Dec 20 '18 at 23:35






    • 32





      @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 '18 at 23:39






    • 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 '18 at 9:26











    • @SebastianMach: well, of course you'd still get some placement new...

      – Matthieu M.
      Dec 22 '18 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 '18 at 12:43





















    • Why do you like not seeing "new" in code?

      – reggaeguitar
      Dec 20 '18 at 23:35






    • 32





      @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 '18 at 23:39






    • 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 '18 at 9:26











    • @SebastianMach: well, of course you'd still get some placement new...

      – Matthieu M.
      Dec 22 '18 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 '18 at 12:43



















    Why do you like not seeing "new" in code?

    – reggaeguitar
    Dec 20 '18 at 23:35





    Why do you like not seeing "new" in code?

    – reggaeguitar
    Dec 20 '18 at 23:35




    32




    32





    @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 '18 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 '18 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 '18 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 '18 at 9:26













    @SebastianMach: well, of course you'd still get some placement new...

    – Matthieu M.
    Dec 22 '18 at 12:06





    @SebastianMach: well, of course you'd still get some placement new...

    – Matthieu M.
    Dec 22 '18 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 '18 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 '18 at 12:43















    38














    make_unique distinguishes T from T and T[N], unique_ptr(new ...) does not.



    You can easily get undefined behaviour by passing a pointer that was newed to a unique_ptr<T>, or by passing a pointer that was newed to a unique_ptr<T>.






    share|improve this answer






























      38














      make_unique distinguishes T from T and T[N], unique_ptr(new ...) does not.



      You can easily get undefined behaviour by passing a pointer that was newed to a unique_ptr<T>, or by passing a pointer that was newed to a unique_ptr<T>.






      share|improve this answer




























        38












        38








        38







        make_unique distinguishes T from T and T[N], unique_ptr(new ...) does not.



        You can easily get undefined behaviour by passing a pointer that was newed to a unique_ptr<T>, or by passing a pointer that was newed to a unique_ptr<T>.






        share|improve this answer















        make_unique distinguishes T from T and T[N], unique_ptr(new ...) does not.



        You can easily get undefined behaviour by passing a pointer that was newed to a unique_ptr<T>, or by passing a pointer that was newed to a unique_ptr<T>.







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Jan 9 at 10:00

























        answered Dec 20 '18 at 15:54









        CalethCaleth

        17.8k22140




        17.8k22140























            20














            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.






            share|improve this answer





















            • 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 '18 at 15:37






            • 2





              In many cases deduction guide would help to eliminate the <MyClass> part in the first variant.

              – AnT
              Dec 20 '18 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 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 '18 at 17:53
















            20














            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.






            share|improve this answer





















            • 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 '18 at 15:37






            • 2





              In many cases deduction guide would help to eliminate the <MyClass> part in the first variant.

              – AnT
              Dec 20 '18 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 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 '18 at 17:53














            20












            20








            20







            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.






            share|improve this answer















            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.







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Dec 21 '18 at 6:39









            Pharap

            2,19612233




            2,19612233










            answered Dec 20 '18 at 14:33









            S.M.S.M.

            6,18241628




            6,18241628








            • 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 '18 at 15:37






            • 2





              In many cases deduction guide would help to eliminate the <MyClass> part in the first variant.

              – AnT
              Dec 20 '18 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 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 '18 at 17:53














            • 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 '18 at 15:37






            • 2





              In many cases deduction guide would help to eliminate the <MyClass> part in the first variant.

              – AnT
              Dec 20 '18 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 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 '18 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 '18 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 '18 at 15:37




            2




            2





            In many cases deduction guide would help to eliminate the <MyClass> part in the first variant.

            – AnT
            Dec 20 '18 at 15:52





            In many cases deduction guide would help to eliminate the <MyClass> part in the first variant.

            – AnT
            Dec 20 '18 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 '18 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 '18 at 17:53











            16














            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.






            share|improve this answer


























            • 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 '18 at 15:57











            • @barry true, overloaded operator new is possible.

              – Yakk - Adam Nevraumont
              Dec 20 '18 at 16:38











            • @dedup what foul C++17 witchcraft is that?

              – Yakk - Adam Nevraumont
              Dec 20 '18 at 16:53






            • 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 '18 at 17:02











            • @Yakk-AdamNevraumont I didn't mean overloading new, I just meant default-init vs value-init.

              – Barry
              Dec 20 '18 at 17:43
















            16














            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.






            share|improve this answer


























            • 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 '18 at 15:57











            • @barry true, overloaded operator new is possible.

              – Yakk - Adam Nevraumont
              Dec 20 '18 at 16:38











            • @dedup what foul C++17 witchcraft is that?

              – Yakk - Adam Nevraumont
              Dec 20 '18 at 16:53






            • 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 '18 at 17:02











            • @Yakk-AdamNevraumont I didn't mean overloading new, I just meant default-init vs value-init.

              – Barry
              Dec 20 '18 at 17:43














            16












            16








            16







            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.






            share|improve this answer















            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.







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Dec 20 '18 at 18:34









            NathanOliver

            94.6k16131202




            94.6k16131202










            answered Dec 20 '18 at 15:52









            Yakk - Adam NevraumontYakk - Adam Nevraumont

            187k20198382




            187k20198382













            • 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 '18 at 15:57











            • @barry true, overloaded operator new is possible.

              – Yakk - Adam Nevraumont
              Dec 20 '18 at 16:38











            • @dedup what foul C++17 witchcraft is that?

              – Yakk - Adam Nevraumont
              Dec 20 '18 at 16:53






            • 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 '18 at 17:02











            • @Yakk-AdamNevraumont I didn't mean overloading new, I just meant default-init vs value-init.

              – Barry
              Dec 20 '18 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 '18 at 15:57











            • @barry true, overloaded operator new is possible.

              – Yakk - Adam Nevraumont
              Dec 20 '18 at 16:38











            • @dedup what foul C++17 witchcraft is that?

              – Yakk - Adam Nevraumont
              Dec 20 '18 at 16:53






            • 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 '18 at 17:02











            • @Yakk-AdamNevraumont I didn't mean overloading new, I just meant default-init vs value-init.

              – Barry
              Dec 20 '18 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 '18 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 '18 at 15:57













            @barry true, overloaded operator new is possible.

            – Yakk - Adam Nevraumont
            Dec 20 '18 at 16:38





            @barry true, overloaded operator new is possible.

            – Yakk - Adam Nevraumont
            Dec 20 '18 at 16:38













            @dedup what foul C++17 witchcraft is that?

            – Yakk - Adam Nevraumont
            Dec 20 '18 at 16:53





            @dedup what foul C++17 witchcraft is that?

            – Yakk - Adam Nevraumont
            Dec 20 '18 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 '18 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 '18 at 17:02













            @Yakk-AdamNevraumont I didn't mean overloading new, I just meant default-init vs value-init.

            – Barry
            Dec 20 '18 at 17:43





            @Yakk-AdamNevraumont I didn't mean overloading new, I just meant default-init vs value-init.

            – Barry
            Dec 20 '18 at 17:43


















            draft saved

            draft discarded




















































            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.




            draft saved


            draft discarded














            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





















































            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







            Popular posts from this blog

            Can a sorcerer learn a 5th-level spell early by creating spell slots using the Font of Magic feature?

            ts Property 'filter' does not exist on type '{}'

            mat-slide-toggle shouldn't change it's state when I click cancel in confirmation window