Storing a unique_ptr with custom deleter in a map

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
7
down vote

favorite












Why doesn't this work?



#include <map>
#include <memory>

void deleter(int* i)
delete i;


std::map<int, std::unique_ptr<int, decltype(&deleter)>> m;

void foo(int* i)
m[0] = std::unique_ptr<int, decltype(&deleter)>(i, &deleter);



Check out the incomprehensible compile error https://godbolt.org/z/Uhp9NO.










share|improve this question



















  • 4




    I don't know why this is getting downvotes, it's a good question. Perhaps it's the link. People might see it as a link to external code. To be clear to other readers, it's a live sample at godbolt. Edit : I've edited the question to make the nature of the link more obvious.
    – François Andrieux
    50 mins ago







  • 2




    You need to post errors here.
    – Maxim Egorushkin
    49 mins ago










  • They are very long, and only a click away. That seem excessive.
    – Timmmm
    49 mins ago










  • This is relevant: stackoverflow.com/questions/17906325/…
    – zoska
    49 mins ago











  • On a mobile it is extremely difficult to view errors from godbolt
    – Robert Andrzejuk
    32 mins ago














up vote
7
down vote

favorite












Why doesn't this work?



#include <map>
#include <memory>

void deleter(int* i)
delete i;


std::map<int, std::unique_ptr<int, decltype(&deleter)>> m;

void foo(int* i)
m[0] = std::unique_ptr<int, decltype(&deleter)>(i, &deleter);



Check out the incomprehensible compile error https://godbolt.org/z/Uhp9NO.










share|improve this question



















  • 4




    I don't know why this is getting downvotes, it's a good question. Perhaps it's the link. People might see it as a link to external code. To be clear to other readers, it's a live sample at godbolt. Edit : I've edited the question to make the nature of the link more obvious.
    – François Andrieux
    50 mins ago







  • 2




    You need to post errors here.
    – Maxim Egorushkin
    49 mins ago










  • They are very long, and only a click away. That seem excessive.
    – Timmmm
    49 mins ago










  • This is relevant: stackoverflow.com/questions/17906325/…
    – zoska
    49 mins ago











  • On a mobile it is extremely difficult to view errors from godbolt
    – Robert Andrzejuk
    32 mins ago












up vote
7
down vote

favorite









up vote
7
down vote

favorite











Why doesn't this work?



#include <map>
#include <memory>

void deleter(int* i)
delete i;


std::map<int, std::unique_ptr<int, decltype(&deleter)>> m;

void foo(int* i)
m[0] = std::unique_ptr<int, decltype(&deleter)>(i, &deleter);



Check out the incomprehensible compile error https://godbolt.org/z/Uhp9NO.










share|improve this question















Why doesn't this work?



#include <map>
#include <memory>

void deleter(int* i)
delete i;


std::map<int, std::unique_ptr<int, decltype(&deleter)>> m;

void foo(int* i)
m[0] = std::unique_ptr<int, decltype(&deleter)>(i, &deleter);



Check out the incomprehensible compile error https://godbolt.org/z/Uhp9NO.







c++ unique-ptr






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited 50 mins ago









François Andrieux

14.3k32244




14.3k32244










asked 53 mins ago









Timmmm

34.6k26183240




34.6k26183240







  • 4




    I don't know why this is getting downvotes, it's a good question. Perhaps it's the link. People might see it as a link to external code. To be clear to other readers, it's a live sample at godbolt. Edit : I've edited the question to make the nature of the link more obvious.
    – François Andrieux
    50 mins ago







  • 2




    You need to post errors here.
    – Maxim Egorushkin
    49 mins ago










  • They are very long, and only a click away. That seem excessive.
    – Timmmm
    49 mins ago










  • This is relevant: stackoverflow.com/questions/17906325/…
    – zoska
    49 mins ago











  • On a mobile it is extremely difficult to view errors from godbolt
    – Robert Andrzejuk
    32 mins ago












  • 4




    I don't know why this is getting downvotes, it's a good question. Perhaps it's the link. People might see it as a link to external code. To be clear to other readers, it's a live sample at godbolt. Edit : I've edited the question to make the nature of the link more obvious.
    – François Andrieux
    50 mins ago







  • 2




    You need to post errors here.
    – Maxim Egorushkin
    49 mins ago










  • They are very long, and only a click away. That seem excessive.
    – Timmmm
    49 mins ago










  • This is relevant: stackoverflow.com/questions/17906325/…
    – zoska
    49 mins ago











  • On a mobile it is extremely difficult to view errors from godbolt
    – Robert Andrzejuk
    32 mins ago







4




4




I don't know why this is getting downvotes, it's a good question. Perhaps it's the link. People might see it as a link to external code. To be clear to other readers, it's a live sample at godbolt. Edit : I've edited the question to make the nature of the link more obvious.
– François Andrieux
50 mins ago





I don't know why this is getting downvotes, it's a good question. Perhaps it's the link. People might see it as a link to external code. To be clear to other readers, it's a live sample at godbolt. Edit : I've edited the question to make the nature of the link more obvious.
– François Andrieux
50 mins ago





2




2




You need to post errors here.
– Maxim Egorushkin
49 mins ago




You need to post errors here.
– Maxim Egorushkin
49 mins ago












They are very long, and only a click away. That seem excessive.
– Timmmm
49 mins ago




They are very long, and only a click away. That seem excessive.
– Timmmm
49 mins ago












This is relevant: stackoverflow.com/questions/17906325/…
– zoska
49 mins ago





This is relevant: stackoverflow.com/questions/17906325/…
– zoska
49 mins ago













On a mobile it is extremely difficult to view errors from godbolt
– Robert Andrzejuk
32 mins ago




On a mobile it is extremely difficult to view errors from godbolt
– Robert Andrzejuk
32 mins ago












2 Answers
2






active

oldest

votes

















up vote
14
down vote



accepted










The problem is that m[0] calls the default constructor of std::unique_ptr<int, decltype(&deleter)>, which is not available because it requires the deleter pointer.



Fix:



struct Deleter 
void operator()(int* i) delete i;
;

std::map<int, std::unique_ptr<int, Deleter>> m;

void foo(int* i)
m[0] = std::unique_ptr<int, Deleter>(i);



This is also more efficient than std::unique_ptr<int, decltype(&deleter)> because it does not have to store the very same pointer to deleter in each instance of std::unique_ptr. I.e. sizeof(std::unique_ptr<int, Deleter>) < sizeof(std::unique_ptr<int, decltype(&deleter)>).






share|improve this answer



























    up vote
    7
    down vote













    std::unique_ptr, when using a custom deleter function like you have, is not default constructable. std::map::operator requires that the value type of the map be default constructable. That means as is you cannot use operator with this type of map.



    In order for std::unique_ptr to be default constructable you need a deleter that satisfies where std::is_default_constructible<Deleter>::value is true and Deleter is not a pointer type.






    share|improve this answer






















      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',
      convertImagesToLinks: true,
      noModals: false,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      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%2f52669202%2fstoring-a-unique-ptr-with-custom-deleter-in-a-map%23new-answer', 'question_page');

      );

      Post as a guest






























      2 Answers
      2






      active

      oldest

      votes








      2 Answers
      2






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes








      up vote
      14
      down vote



      accepted










      The problem is that m[0] calls the default constructor of std::unique_ptr<int, decltype(&deleter)>, which is not available because it requires the deleter pointer.



      Fix:



      struct Deleter 
      void operator()(int* i) delete i;
      ;

      std::map<int, std::unique_ptr<int, Deleter>> m;

      void foo(int* i)
      m[0] = std::unique_ptr<int, Deleter>(i);



      This is also more efficient than std::unique_ptr<int, decltype(&deleter)> because it does not have to store the very same pointer to deleter in each instance of std::unique_ptr. I.e. sizeof(std::unique_ptr<int, Deleter>) < sizeof(std::unique_ptr<int, decltype(&deleter)>).






      share|improve this answer
























        up vote
        14
        down vote



        accepted










        The problem is that m[0] calls the default constructor of std::unique_ptr<int, decltype(&deleter)>, which is not available because it requires the deleter pointer.



        Fix:



        struct Deleter 
        void operator()(int* i) delete i;
        ;

        std::map<int, std::unique_ptr<int, Deleter>> m;

        void foo(int* i)
        m[0] = std::unique_ptr<int, Deleter>(i);



        This is also more efficient than std::unique_ptr<int, decltype(&deleter)> because it does not have to store the very same pointer to deleter in each instance of std::unique_ptr. I.e. sizeof(std::unique_ptr<int, Deleter>) < sizeof(std::unique_ptr<int, decltype(&deleter)>).






        share|improve this answer






















          up vote
          14
          down vote



          accepted







          up vote
          14
          down vote



          accepted






          The problem is that m[0] calls the default constructor of std::unique_ptr<int, decltype(&deleter)>, which is not available because it requires the deleter pointer.



          Fix:



          struct Deleter 
          void operator()(int* i) delete i;
          ;

          std::map<int, std::unique_ptr<int, Deleter>> m;

          void foo(int* i)
          m[0] = std::unique_ptr<int, Deleter>(i);



          This is also more efficient than std::unique_ptr<int, decltype(&deleter)> because it does not have to store the very same pointer to deleter in each instance of std::unique_ptr. I.e. sizeof(std::unique_ptr<int, Deleter>) < sizeof(std::unique_ptr<int, decltype(&deleter)>).






          share|improve this answer












          The problem is that m[0] calls the default constructor of std::unique_ptr<int, decltype(&deleter)>, which is not available because it requires the deleter pointer.



          Fix:



          struct Deleter 
          void operator()(int* i) delete i;
          ;

          std::map<int, std::unique_ptr<int, Deleter>> m;

          void foo(int* i)
          m[0] = std::unique_ptr<int, Deleter>(i);



          This is also more efficient than std::unique_ptr<int, decltype(&deleter)> because it does not have to store the very same pointer to deleter in each instance of std::unique_ptr. I.e. sizeof(std::unique_ptr<int, Deleter>) < sizeof(std::unique_ptr<int, decltype(&deleter)>).







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered 49 mins ago









          Maxim Egorushkin

          81.3k1195178




          81.3k1195178






















              up vote
              7
              down vote













              std::unique_ptr, when using a custom deleter function like you have, is not default constructable. std::map::operator requires that the value type of the map be default constructable. That means as is you cannot use operator with this type of map.



              In order for std::unique_ptr to be default constructable you need a deleter that satisfies where std::is_default_constructible<Deleter>::value is true and Deleter is not a pointer type.






              share|improve this answer


























                up vote
                7
                down vote













                std::unique_ptr, when using a custom deleter function like you have, is not default constructable. std::map::operator requires that the value type of the map be default constructable. That means as is you cannot use operator with this type of map.



                In order for std::unique_ptr to be default constructable you need a deleter that satisfies where std::is_default_constructible<Deleter>::value is true and Deleter is not a pointer type.






                share|improve this answer
























                  up vote
                  7
                  down vote










                  up vote
                  7
                  down vote









                  std::unique_ptr, when using a custom deleter function like you have, is not default constructable. std::map::operator requires that the value type of the map be default constructable. That means as is you cannot use operator with this type of map.



                  In order for std::unique_ptr to be default constructable you need a deleter that satisfies where std::is_default_constructible<Deleter>::value is true and Deleter is not a pointer type.






                  share|improve this answer














                  std::unique_ptr, when using a custom deleter function like you have, is not default constructable. std::map::operator requires that the value type of the map be default constructable. That means as is you cannot use operator with this type of map.



                  In order for std::unique_ptr to be default constructable you need a deleter that satisfies where std::is_default_constructible<Deleter>::value is true and Deleter is not a pointer type.







                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited 43 mins ago

























                  answered 49 mins ago









                  NathanOliver

                  77.5k15104158




                  77.5k15104158



























                       

                      draft saved


                      draft discarded















































                       


                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function ()
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f52669202%2fstoring-a-unique-ptr-with-custom-deleter-in-a-map%23new-answer', 'question_page');

                      );

                      Post as a guest













































































                      Comments

                      Popular posts from this blog

                      Long meetings (6-7 hours a day): Being “babysat” by supervisor

                      What does second last employer means? [closed]

                      One-line joke