Why try_emplace is not implemented for std::multimap











up vote
6
down vote

favorite












c++17 introduces try_emplace method for std::map, so now I can write code like below



struct Test
{
Test(int i, int j){}
};
std::map<int, Test> tmap;
tmap.try_emplace(10, 10, 10);


but there is no try_emplace for std::multimap, so piecewise_construct is still needed.



Is there a technical reason for this?










share|improve this question




















  • 1




    std::multimap does not need try_emplace as it always inserts, so emplace is enough.
    – Slava
    4 hours ago










  • I see, but it's really handy if piecewise_construct can be get rid of for std::multimap
    – Lei Yu
    33 mins ago















up vote
6
down vote

favorite












c++17 introduces try_emplace method for std::map, so now I can write code like below



struct Test
{
Test(int i, int j){}
};
std::map<int, Test> tmap;
tmap.try_emplace(10, 10, 10);


but there is no try_emplace for std::multimap, so piecewise_construct is still needed.



Is there a technical reason for this?










share|improve this question




















  • 1




    std::multimap does not need try_emplace as it always inserts, so emplace is enough.
    – Slava
    4 hours ago










  • I see, but it's really handy if piecewise_construct can be get rid of for std::multimap
    – Lei Yu
    33 mins ago













up vote
6
down vote

favorite









up vote
6
down vote

favorite











c++17 introduces try_emplace method for std::map, so now I can write code like below



struct Test
{
Test(int i, int j){}
};
std::map<int, Test> tmap;
tmap.try_emplace(10, 10, 10);


but there is no try_emplace for std::multimap, so piecewise_construct is still needed.



Is there a technical reason for this?










share|improve this question















c++17 introduces try_emplace method for std::map, so now I can write code like below



struct Test
{
Test(int i, int j){}
};
std::map<int, Test> tmap;
tmap.try_emplace(10, 10, 10);


but there is no try_emplace for std::multimap, so piecewise_construct is still needed.



Is there a technical reason for this?







c++ c++17






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited 53 mins ago









Shafik Yaghmour

125k23320527




125k23320527










asked 5 hours ago









Lei Yu

484




484








  • 1




    std::multimap does not need try_emplace as it always inserts, so emplace is enough.
    – Slava
    4 hours ago










  • I see, but it's really handy if piecewise_construct can be get rid of for std::multimap
    – Lei Yu
    33 mins ago














  • 1




    std::multimap does not need try_emplace as it always inserts, so emplace is enough.
    – Slava
    4 hours ago










  • I see, but it's really handy if piecewise_construct can be get rid of for std::multimap
    – Lei Yu
    33 mins ago








1




1




std::multimap does not need try_emplace as it always inserts, so emplace is enough.
– Slava
4 hours ago




std::multimap does not need try_emplace as it always inserts, so emplace is enough.
– Slava
4 hours ago












I see, but it's really handy if piecewise_construct can be get rid of for std::multimap
– Lei Yu
33 mins ago




I see, but it's really handy if piecewise_construct can be get rid of for std::multimap
– Lei Yu
33 mins ago












2 Answers
2






active

oldest

votes

















up vote
4
down vote













As pointed out in the comments it is not necessary. The rational for adding it to map was all the error prone code needed to deal with the case that key already exits, see the proposal n4279 (emphasis mine):




The existing interface of unique-keyed map containers (std::map,
std::unordered_map) is slightly underspecified, which makes certain
container mutations more complicated to write and error-prone than
necessary
. This paper describes new member function templates to
fill this gap.



The justification and rationale for the new interface are given in
N3873. The initial reaction to N3873 in Issaquah was that the existing
map interfaces should be fixed rather than adding new interfaces. We
explored this idea in N4006 in Rapperswil and decided that the
original proposal was preferable (with some name changes). This paper
only summarises the proposed extension without repeating the original
discussion. We only restate the motivating code snippet here for
motivation:



std::map<std::string, std::unique_ptr<Foo>> m;
m["foo"] = nullptr;

auto ptr = std::make_unique_ptr<Foo>;
auto res = m.emplace("foo", std::move(ptr));

assert(ptr); // ??? (may or may not fire)






share|improve this answer

















  • 1




    thanks for the explanation, but it's kind of against intuition that ptr would still be valid after std::move is called on it.
    – Lei Yu
    36 mins ago










  • @LeiYu I believe the answer here explains the issues with emplace and unique_ptr and why this is the case.
    – Shafik Yaghmour
    7 mins ago


















up vote
3
down vote














is there a technical reason for this?




Yes. The purpose of try_emplace() is to not do anything if the key already exists in the map. But for std::{unordered_,}multi{map,set}, you can have multiple values for each key. That is, indeed, the point of these containers: to have multiple values for a given key.



As a result, try_emplace() cannot fail for these containers - so it would be confusing and pointless to provide such a function.






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: 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%2f53772218%2fwhy-try-emplace-is-not-implemented-for-stdmultimap%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    4
    down vote













    As pointed out in the comments it is not necessary. The rational for adding it to map was all the error prone code needed to deal with the case that key already exits, see the proposal n4279 (emphasis mine):




    The existing interface of unique-keyed map containers (std::map,
    std::unordered_map) is slightly underspecified, which makes certain
    container mutations more complicated to write and error-prone than
    necessary
    . This paper describes new member function templates to
    fill this gap.



    The justification and rationale for the new interface are given in
    N3873. The initial reaction to N3873 in Issaquah was that the existing
    map interfaces should be fixed rather than adding new interfaces. We
    explored this idea in N4006 in Rapperswil and decided that the
    original proposal was preferable (with some name changes). This paper
    only summarises the proposed extension without repeating the original
    discussion. We only restate the motivating code snippet here for
    motivation:



    std::map<std::string, std::unique_ptr<Foo>> m;
    m["foo"] = nullptr;

    auto ptr = std::make_unique_ptr<Foo>;
    auto res = m.emplace("foo", std::move(ptr));

    assert(ptr); // ??? (may or may not fire)






    share|improve this answer

















    • 1




      thanks for the explanation, but it's kind of against intuition that ptr would still be valid after std::move is called on it.
      – Lei Yu
      36 mins ago










    • @LeiYu I believe the answer here explains the issues with emplace and unique_ptr and why this is the case.
      – Shafik Yaghmour
      7 mins ago















    up vote
    4
    down vote













    As pointed out in the comments it is not necessary. The rational for adding it to map was all the error prone code needed to deal with the case that key already exits, see the proposal n4279 (emphasis mine):




    The existing interface of unique-keyed map containers (std::map,
    std::unordered_map) is slightly underspecified, which makes certain
    container mutations more complicated to write and error-prone than
    necessary
    . This paper describes new member function templates to
    fill this gap.



    The justification and rationale for the new interface are given in
    N3873. The initial reaction to N3873 in Issaquah was that the existing
    map interfaces should be fixed rather than adding new interfaces. We
    explored this idea in N4006 in Rapperswil and decided that the
    original proposal was preferable (with some name changes). This paper
    only summarises the proposed extension without repeating the original
    discussion. We only restate the motivating code snippet here for
    motivation:



    std::map<std::string, std::unique_ptr<Foo>> m;
    m["foo"] = nullptr;

    auto ptr = std::make_unique_ptr<Foo>;
    auto res = m.emplace("foo", std::move(ptr));

    assert(ptr); // ??? (may or may not fire)






    share|improve this answer

















    • 1




      thanks for the explanation, but it's kind of against intuition that ptr would still be valid after std::move is called on it.
      – Lei Yu
      36 mins ago










    • @LeiYu I believe the answer here explains the issues with emplace and unique_ptr and why this is the case.
      – Shafik Yaghmour
      7 mins ago













    up vote
    4
    down vote










    up vote
    4
    down vote









    As pointed out in the comments it is not necessary. The rational for adding it to map was all the error prone code needed to deal with the case that key already exits, see the proposal n4279 (emphasis mine):




    The existing interface of unique-keyed map containers (std::map,
    std::unordered_map) is slightly underspecified, which makes certain
    container mutations more complicated to write and error-prone than
    necessary
    . This paper describes new member function templates to
    fill this gap.



    The justification and rationale for the new interface are given in
    N3873. The initial reaction to N3873 in Issaquah was that the existing
    map interfaces should be fixed rather than adding new interfaces. We
    explored this idea in N4006 in Rapperswil and decided that the
    original proposal was preferable (with some name changes). This paper
    only summarises the proposed extension without repeating the original
    discussion. We only restate the motivating code snippet here for
    motivation:



    std::map<std::string, std::unique_ptr<Foo>> m;
    m["foo"] = nullptr;

    auto ptr = std::make_unique_ptr<Foo>;
    auto res = m.emplace("foo", std::move(ptr));

    assert(ptr); // ??? (may or may not fire)






    share|improve this answer












    As pointed out in the comments it is not necessary. The rational for adding it to map was all the error prone code needed to deal with the case that key already exits, see the proposal n4279 (emphasis mine):




    The existing interface of unique-keyed map containers (std::map,
    std::unordered_map) is slightly underspecified, which makes certain
    container mutations more complicated to write and error-prone than
    necessary
    . This paper describes new member function templates to
    fill this gap.



    The justification and rationale for the new interface are given in
    N3873. The initial reaction to N3873 in Issaquah was that the existing
    map interfaces should be fixed rather than adding new interfaces. We
    explored this idea in N4006 in Rapperswil and decided that the
    original proposal was preferable (with some name changes). This paper
    only summarises the proposed extension without repeating the original
    discussion. We only restate the motivating code snippet here for
    motivation:



    std::map<std::string, std::unique_ptr<Foo>> m;
    m["foo"] = nullptr;

    auto ptr = std::make_unique_ptr<Foo>;
    auto res = m.emplace("foo", std::move(ptr));

    assert(ptr); // ??? (may or may not fire)







    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered 4 hours ago









    Shafik Yaghmour

    125k23320527




    125k23320527








    • 1




      thanks for the explanation, but it's kind of against intuition that ptr would still be valid after std::move is called on it.
      – Lei Yu
      36 mins ago










    • @LeiYu I believe the answer here explains the issues with emplace and unique_ptr and why this is the case.
      – Shafik Yaghmour
      7 mins ago














    • 1




      thanks for the explanation, but it's kind of against intuition that ptr would still be valid after std::move is called on it.
      – Lei Yu
      36 mins ago










    • @LeiYu I believe the answer here explains the issues with emplace and unique_ptr and why this is the case.
      – Shafik Yaghmour
      7 mins ago








    1




    1




    thanks for the explanation, but it's kind of against intuition that ptr would still be valid after std::move is called on it.
    – Lei Yu
    36 mins ago




    thanks for the explanation, but it's kind of against intuition that ptr would still be valid after std::move is called on it.
    – Lei Yu
    36 mins ago












    @LeiYu I believe the answer here explains the issues with emplace and unique_ptr and why this is the case.
    – Shafik Yaghmour
    7 mins ago




    @LeiYu I believe the answer here explains the issues with emplace and unique_ptr and why this is the case.
    – Shafik Yaghmour
    7 mins ago












    up vote
    3
    down vote














    is there a technical reason for this?




    Yes. The purpose of try_emplace() is to not do anything if the key already exists in the map. But for std::{unordered_,}multi{map,set}, you can have multiple values for each key. That is, indeed, the point of these containers: to have multiple values for a given key.



    As a result, try_emplace() cannot fail for these containers - so it would be confusing and pointless to provide such a function.






    share|improve this answer

























      up vote
      3
      down vote














      is there a technical reason for this?




      Yes. The purpose of try_emplace() is to not do anything if the key already exists in the map. But for std::{unordered_,}multi{map,set}, you can have multiple values for each key. That is, indeed, the point of these containers: to have multiple values for a given key.



      As a result, try_emplace() cannot fail for these containers - so it would be confusing and pointless to provide such a function.






      share|improve this answer























        up vote
        3
        down vote










        up vote
        3
        down vote










        is there a technical reason for this?




        Yes. The purpose of try_emplace() is to not do anything if the key already exists in the map. But for std::{unordered_,}multi{map,set}, you can have multiple values for each key. That is, indeed, the point of these containers: to have multiple values for a given key.



        As a result, try_emplace() cannot fail for these containers - so it would be confusing and pointless to provide such a function.






        share|improve this answer













        is there a technical reason for this?




        Yes. The purpose of try_emplace() is to not do anything if the key already exists in the map. But for std::{unordered_,}multi{map,set}, you can have multiple values for each key. That is, indeed, the point of these containers: to have multiple values for a given key.



        As a result, try_emplace() cannot fail for these containers - so it would be confusing and pointless to provide such a function.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered 4 hours ago









        Barry

        175k18299554




        175k18299554






























            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.





            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.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53772218%2fwhy-try-emplace-is-not-implemented-for-stdmultimap%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

            サソリ

            広島県道265号伴広島線

            Setup Asymptote in Texstudio