does vs2017 need explict move constructor declaration

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











up vote
10
down vote

favorite
3












The below code can be compiled successfully using vs2015, but failed using vs2017. vs2017 report "error C2280: “std::pair<const _Kty,_Ty>::pair(const std::pair<const _Kty,_Ty> &)”: attempting to reference a deleted function".



#include <unordered_map>
#include <memory>

struct Node

std::unordered_map<int, std::unique_ptr<int>> map_;
//uncomment the following two lines will pass vs2017 compile
//Node(Node&& o) = default;
//Node() = default;
;

int main()

std::vector<Node> vec;
Node node;
vec.push_back(std::move(node));
return 0;



It looks like vs2017 need explict move constructor declaration. could anybody explain the reason? thanks.










share|improve this question







New contributor




finn is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.



















  • You're missing #include <vector> but as far as I can tell, that code should compile (and it does on e.g. GCC 8.2). Do you have the latest and greatest VS2017?
    – rubenvb
    4 hours ago











  • I can confirm this code fails with error code under vs2017 15.4.2.
    – marcinj
    3 hours ago










  • Confirm also in the VS2017 15.9.0 Preview 3.
    – Evg
    3 hours ago














up vote
10
down vote

favorite
3












The below code can be compiled successfully using vs2015, but failed using vs2017. vs2017 report "error C2280: “std::pair<const _Kty,_Ty>::pair(const std::pair<const _Kty,_Ty> &)”: attempting to reference a deleted function".



#include <unordered_map>
#include <memory>

struct Node

std::unordered_map<int, std::unique_ptr<int>> map_;
//uncomment the following two lines will pass vs2017 compile
//Node(Node&& o) = default;
//Node() = default;
;

int main()

std::vector<Node> vec;
Node node;
vec.push_back(std::move(node));
return 0;



It looks like vs2017 need explict move constructor declaration. could anybody explain the reason? thanks.










share|improve this question







New contributor




finn is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.



















  • You're missing #include <vector> but as far as I can tell, that code should compile (and it does on e.g. GCC 8.2). Do you have the latest and greatest VS2017?
    – rubenvb
    4 hours ago











  • I can confirm this code fails with error code under vs2017 15.4.2.
    – marcinj
    3 hours ago










  • Confirm also in the VS2017 15.9.0 Preview 3.
    – Evg
    3 hours ago












up vote
10
down vote

favorite
3









up vote
10
down vote

favorite
3






3





The below code can be compiled successfully using vs2015, but failed using vs2017. vs2017 report "error C2280: “std::pair<const _Kty,_Ty>::pair(const std::pair<const _Kty,_Ty> &)”: attempting to reference a deleted function".



#include <unordered_map>
#include <memory>

struct Node

std::unordered_map<int, std::unique_ptr<int>> map_;
//uncomment the following two lines will pass vs2017 compile
//Node(Node&& o) = default;
//Node() = default;
;

int main()

std::vector<Node> vec;
Node node;
vec.push_back(std::move(node));
return 0;



It looks like vs2017 need explict move constructor declaration. could anybody explain the reason? thanks.










share|improve this question







New contributor




finn is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











The below code can be compiled successfully using vs2015, but failed using vs2017. vs2017 report "error C2280: “std::pair<const _Kty,_Ty>::pair(const std::pair<const _Kty,_Ty> &)”: attempting to reference a deleted function".



#include <unordered_map>
#include <memory>

struct Node

std::unordered_map<int, std::unique_ptr<int>> map_;
//uncomment the following two lines will pass vs2017 compile
//Node(Node&& o) = default;
//Node() = default;
;

int main()

std::vector<Node> vec;
Node node;
vec.push_back(std::move(node));
return 0;



It looks like vs2017 need explict move constructor declaration. could anybody explain the reason? thanks.







c++ visual-studio-2017 move-constructor






share|improve this question







New contributor




finn is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











share|improve this question







New contributor




finn is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









share|improve this question




share|improve this question






New contributor




finn is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









asked 4 hours ago









finn

541




541




New contributor




finn is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.





New contributor





finn is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.






finn is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











  • You're missing #include <vector> but as far as I can tell, that code should compile (and it does on e.g. GCC 8.2). Do you have the latest and greatest VS2017?
    – rubenvb
    4 hours ago











  • I can confirm this code fails with error code under vs2017 15.4.2.
    – marcinj
    3 hours ago










  • Confirm also in the VS2017 15.9.0 Preview 3.
    – Evg
    3 hours ago
















  • You're missing #include <vector> but as far as I can tell, that code should compile (and it does on e.g. GCC 8.2). Do you have the latest and greatest VS2017?
    – rubenvb
    4 hours ago











  • I can confirm this code fails with error code under vs2017 15.4.2.
    – marcinj
    3 hours ago










  • Confirm also in the VS2017 15.9.0 Preview 3.
    – Evg
    3 hours ago















You're missing #include <vector> but as far as I can tell, that code should compile (and it does on e.g. GCC 8.2). Do you have the latest and greatest VS2017?
– rubenvb
4 hours ago





You're missing #include <vector> but as far as I can tell, that code should compile (and it does on e.g. GCC 8.2). Do you have the latest and greatest VS2017?
– rubenvb
4 hours ago













I can confirm this code fails with error code under vs2017 15.4.2.
– marcinj
3 hours ago




I can confirm this code fails with error code under vs2017 15.4.2.
– marcinj
3 hours ago












Confirm also in the VS2017 15.9.0 Preview 3.
– Evg
3 hours ago




Confirm also in the VS2017 15.9.0 Preview 3.
– Evg
3 hours ago












3 Answers
3






active

oldest

votes

















up vote
4
down vote













When you declare a move constructor, the implicitly declared copy constructor is defined as deleted. On the other hand, when you don't declare a move constructor, the compiler implicitly defines the copy constructor when it need it. And this implicit definition is ill-formed.



unique_ptr is not CopyInsertable in a container that uses a standard allocator because it is not copy constructible so the copy constructor of map_ is ill-formed (it could have been declared as deleted, but this is not required by the standard).



As your example code show us, with newer version of MSVC, this ill-formed definition is generated with this example code. I do not think there is something in the standard that forbids it (even if this is realy surprising).



So you should indeed ensure that the copy constructor of Node is declared or implicitly defined as deleted.






share|improve this answer


















  • 1




    Im wondering as to why the issue is not seen with clang or gcc ?
    – darune
    1 hour ago










  • @darune because the generation of the code of the copy constructor is only performed when needed. So the error does not appear within this small example but it may in a larger piece of code.
    – Oliv
    1 hour ago











  • @darune What do you think about that :godbolt.org/z/KG02ua ,
    – Oliv
    1 hour ago






  • 1




    @darune I think the bug is in the standard requirement. If a standard type is not copy constructible it should be possible to check it with traits. But actually implementing such a requirement would be a real pain. I hope that with concepts this will be fixed.
    – Oliv
    1 hour ago






  • 1




    I don't have VS2017 accessible, but couldn't be the problem with that implicitly-declared move constructor of std::unordered_map (and therefore of Node) is not noexcept? Then, push_back, i.e., emplace_back, may prefer copy constructor (during reallocation) than potentially throwing move constructor (std::move_if_noexcept)? With user-declared move constructor, the copy constructor is deleted, so throwing move constructor will be used.
    – Daniel Langr
    40 mins ago


















up vote
3
down vote













I believe this is a bug, since the same error can be triggered by the following minimal code:



#include <memory>
#include <unordered_map>
#include <vector>

int main()
std::vector<std::unordered_map<int, std::unique_ptr<int>>> vec;
vec.reserve(1);



Live demo on GodBolt: https://godbolt.org/z/VApPkH.




Another example:



#include <set>
#include <vector>

struct NonCopyable
NonCopyable(const NonCopyable&) = delete;
NonCopyable(NonCopyable&&) noexcept = default;
;

int main()
std::vector<std::set<NonCopyable>> vec;
vec.reserve(1);






share|improve this answer





























    up vote
    2
    down vote













    Let's look at the std::vector source code (I replaced pointer and _Ty with actual types):



    void _Umove_if_noexcept1(Node* First, Node* Last, Node* Dest, true_type)
    // move [First, Last) to raw Dest, using allocator
    _Uninitialized_move(First, Last, Dest, this->_Getal());


    void _Umove_if_noexcept1(Node* First, Node* Last, Node* Dest, false_type)
    // copy [First, Last) to raw Dest, using allocator
    _Uninitialized_copy(First, Last, Dest, this->_Getal());


    void _Umove_if_noexcept(Node* First, Node* Last, Node* Dest)
    // move_if_noexcept [First, Last) to raw Dest, using allocator
    _Umove_if_noexcept1(First, Last, Dest,
    bool_constant<disjunction_v<is_nothrow_move_constructible<Node>, negation<is_copy_constructible<Node>>>>);



    If Node is no-throw move-constructible or is not copy-constructible, _Uninitialized_move is called. If Node is not no-throw move-constructible and is copy-constructible, _Uninitialized_copy is called.



    The problem is that the type trait std::is_copy_constructible is std::true_type for Node if you do not declare a move constructor explicitly. This declaration makes copy-constructor deleted.






    share|improve this answer


















    • 1




      Im wondering as to why the issue is not seen with clang or gcc ?
      – darune
      1 hour ago






    • 1




      @darune, the dumb answer is because gcc's and clang's implementations do not rely on std::is_copy_constructible in this particular piece of code. I don't have a better answer now.
      – Evg
      1 hour ago










    • If i understand you correctly that code is in the MSVC vector implementation (?) and isn't that a bug in this case ? It does feel like like a bug, because invoking the move constructor directly does compile fine.
      – darune
      1 hour ago











    • @darune, yes, the code in my answer is directly from MSVC STL implementation. I agree that it feels like a bug.
      – Evg
      38 mins ago










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



    );






    finn is a new contributor. Be nice, and check out our Code of Conduct.









     

    draft saved


    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53168836%2fdoes-vs2017-need-explict-move-constructor-declaration%23new-answer', 'question_page');

    );

    Post as a guest






























    3 Answers
    3






    active

    oldest

    votes








    3 Answers
    3






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    4
    down vote













    When you declare a move constructor, the implicitly declared copy constructor is defined as deleted. On the other hand, when you don't declare a move constructor, the compiler implicitly defines the copy constructor when it need it. And this implicit definition is ill-formed.



    unique_ptr is not CopyInsertable in a container that uses a standard allocator because it is not copy constructible so the copy constructor of map_ is ill-formed (it could have been declared as deleted, but this is not required by the standard).



    As your example code show us, with newer version of MSVC, this ill-formed definition is generated with this example code. I do not think there is something in the standard that forbids it (even if this is realy surprising).



    So you should indeed ensure that the copy constructor of Node is declared or implicitly defined as deleted.






    share|improve this answer


















    • 1




      Im wondering as to why the issue is not seen with clang or gcc ?
      – darune
      1 hour ago










    • @darune because the generation of the code of the copy constructor is only performed when needed. So the error does not appear within this small example but it may in a larger piece of code.
      – Oliv
      1 hour ago











    • @darune What do you think about that :godbolt.org/z/KG02ua ,
      – Oliv
      1 hour ago






    • 1




      @darune I think the bug is in the standard requirement. If a standard type is not copy constructible it should be possible to check it with traits. But actually implementing such a requirement would be a real pain. I hope that with concepts this will be fixed.
      – Oliv
      1 hour ago






    • 1




      I don't have VS2017 accessible, but couldn't be the problem with that implicitly-declared move constructor of std::unordered_map (and therefore of Node) is not noexcept? Then, push_back, i.e., emplace_back, may prefer copy constructor (during reallocation) than potentially throwing move constructor (std::move_if_noexcept)? With user-declared move constructor, the copy constructor is deleted, so throwing move constructor will be used.
      – Daniel Langr
      40 mins ago















    up vote
    4
    down vote













    When you declare a move constructor, the implicitly declared copy constructor is defined as deleted. On the other hand, when you don't declare a move constructor, the compiler implicitly defines the copy constructor when it need it. And this implicit definition is ill-formed.



    unique_ptr is not CopyInsertable in a container that uses a standard allocator because it is not copy constructible so the copy constructor of map_ is ill-formed (it could have been declared as deleted, but this is not required by the standard).



    As your example code show us, with newer version of MSVC, this ill-formed definition is generated with this example code. I do not think there is something in the standard that forbids it (even if this is realy surprising).



    So you should indeed ensure that the copy constructor of Node is declared or implicitly defined as deleted.






    share|improve this answer


















    • 1




      Im wondering as to why the issue is not seen with clang or gcc ?
      – darune
      1 hour ago










    • @darune because the generation of the code of the copy constructor is only performed when needed. So the error does not appear within this small example but it may in a larger piece of code.
      – Oliv
      1 hour ago











    • @darune What do you think about that :godbolt.org/z/KG02ua ,
      – Oliv
      1 hour ago






    • 1




      @darune I think the bug is in the standard requirement. If a standard type is not copy constructible it should be possible to check it with traits. But actually implementing such a requirement would be a real pain. I hope that with concepts this will be fixed.
      – Oliv
      1 hour ago






    • 1




      I don't have VS2017 accessible, but couldn't be the problem with that implicitly-declared move constructor of std::unordered_map (and therefore of Node) is not noexcept? Then, push_back, i.e., emplace_back, may prefer copy constructor (during reallocation) than potentially throwing move constructor (std::move_if_noexcept)? With user-declared move constructor, the copy constructor is deleted, so throwing move constructor will be used.
      – Daniel Langr
      40 mins ago













    up vote
    4
    down vote










    up vote
    4
    down vote









    When you declare a move constructor, the implicitly declared copy constructor is defined as deleted. On the other hand, when you don't declare a move constructor, the compiler implicitly defines the copy constructor when it need it. And this implicit definition is ill-formed.



    unique_ptr is not CopyInsertable in a container that uses a standard allocator because it is not copy constructible so the copy constructor of map_ is ill-formed (it could have been declared as deleted, but this is not required by the standard).



    As your example code show us, with newer version of MSVC, this ill-formed definition is generated with this example code. I do not think there is something in the standard that forbids it (even if this is realy surprising).



    So you should indeed ensure that the copy constructor of Node is declared or implicitly defined as deleted.






    share|improve this answer














    When you declare a move constructor, the implicitly declared copy constructor is defined as deleted. On the other hand, when you don't declare a move constructor, the compiler implicitly defines the copy constructor when it need it. And this implicit definition is ill-formed.



    unique_ptr is not CopyInsertable in a container that uses a standard allocator because it is not copy constructible so the copy constructor of map_ is ill-formed (it could have been declared as deleted, but this is not required by the standard).



    As your example code show us, with newer version of MSVC, this ill-formed definition is generated with this example code. I do not think there is something in the standard that forbids it (even if this is realy surprising).



    So you should indeed ensure that the copy constructor of Node is declared or implicitly defined as deleted.







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited 1 hour ago

























    answered 1 hour ago









    Oliv

    7,1231750




    7,1231750







    • 1




      Im wondering as to why the issue is not seen with clang or gcc ?
      – darune
      1 hour ago










    • @darune because the generation of the code of the copy constructor is only performed when needed. So the error does not appear within this small example but it may in a larger piece of code.
      – Oliv
      1 hour ago











    • @darune What do you think about that :godbolt.org/z/KG02ua ,
      – Oliv
      1 hour ago






    • 1




      @darune I think the bug is in the standard requirement. If a standard type is not copy constructible it should be possible to check it with traits. But actually implementing such a requirement would be a real pain. I hope that with concepts this will be fixed.
      – Oliv
      1 hour ago






    • 1




      I don't have VS2017 accessible, but couldn't be the problem with that implicitly-declared move constructor of std::unordered_map (and therefore of Node) is not noexcept? Then, push_back, i.e., emplace_back, may prefer copy constructor (during reallocation) than potentially throwing move constructor (std::move_if_noexcept)? With user-declared move constructor, the copy constructor is deleted, so throwing move constructor will be used.
      – Daniel Langr
      40 mins ago













    • 1




      Im wondering as to why the issue is not seen with clang or gcc ?
      – darune
      1 hour ago










    • @darune because the generation of the code of the copy constructor is only performed when needed. So the error does not appear within this small example but it may in a larger piece of code.
      – Oliv
      1 hour ago











    • @darune What do you think about that :godbolt.org/z/KG02ua ,
      – Oliv
      1 hour ago






    • 1




      @darune I think the bug is in the standard requirement. If a standard type is not copy constructible it should be possible to check it with traits. But actually implementing such a requirement would be a real pain. I hope that with concepts this will be fixed.
      – Oliv
      1 hour ago






    • 1




      I don't have VS2017 accessible, but couldn't be the problem with that implicitly-declared move constructor of std::unordered_map (and therefore of Node) is not noexcept? Then, push_back, i.e., emplace_back, may prefer copy constructor (during reallocation) than potentially throwing move constructor (std::move_if_noexcept)? With user-declared move constructor, the copy constructor is deleted, so throwing move constructor will be used.
      – Daniel Langr
      40 mins ago








    1




    1




    Im wondering as to why the issue is not seen with clang or gcc ?
    – darune
    1 hour ago




    Im wondering as to why the issue is not seen with clang or gcc ?
    – darune
    1 hour ago












    @darune because the generation of the code of the copy constructor is only performed when needed. So the error does not appear within this small example but it may in a larger piece of code.
    – Oliv
    1 hour ago





    @darune because the generation of the code of the copy constructor is only performed when needed. So the error does not appear within this small example but it may in a larger piece of code.
    – Oliv
    1 hour ago













    @darune What do you think about that :godbolt.org/z/KG02ua ,
    – Oliv
    1 hour ago




    @darune What do you think about that :godbolt.org/z/KG02ua ,
    – Oliv
    1 hour ago




    1




    1




    @darune I think the bug is in the standard requirement. If a standard type is not copy constructible it should be possible to check it with traits. But actually implementing such a requirement would be a real pain. I hope that with concepts this will be fixed.
    – Oliv
    1 hour ago




    @darune I think the bug is in the standard requirement. If a standard type is not copy constructible it should be possible to check it with traits. But actually implementing such a requirement would be a real pain. I hope that with concepts this will be fixed.
    – Oliv
    1 hour ago




    1




    1




    I don't have VS2017 accessible, but couldn't be the problem with that implicitly-declared move constructor of std::unordered_map (and therefore of Node) is not noexcept? Then, push_back, i.e., emplace_back, may prefer copy constructor (during reallocation) than potentially throwing move constructor (std::move_if_noexcept)? With user-declared move constructor, the copy constructor is deleted, so throwing move constructor will be used.
    – Daniel Langr
    40 mins ago





    I don't have VS2017 accessible, but couldn't be the problem with that implicitly-declared move constructor of std::unordered_map (and therefore of Node) is not noexcept? Then, push_back, i.e., emplace_back, may prefer copy constructor (during reallocation) than potentially throwing move constructor (std::move_if_noexcept)? With user-declared move constructor, the copy constructor is deleted, so throwing move constructor will be used.
    – Daniel Langr
    40 mins ago













    up vote
    3
    down vote













    I believe this is a bug, since the same error can be triggered by the following minimal code:



    #include <memory>
    #include <unordered_map>
    #include <vector>

    int main()
    std::vector<std::unordered_map<int, std::unique_ptr<int>>> vec;
    vec.reserve(1);



    Live demo on GodBolt: https://godbolt.org/z/VApPkH.




    Another example:



    #include <set>
    #include <vector>

    struct NonCopyable
    NonCopyable(const NonCopyable&) = delete;
    NonCopyable(NonCopyable&&) noexcept = default;
    ;

    int main()
    std::vector<std::set<NonCopyable>> vec;
    vec.reserve(1);






    share|improve this answer


























      up vote
      3
      down vote













      I believe this is a bug, since the same error can be triggered by the following minimal code:



      #include <memory>
      #include <unordered_map>
      #include <vector>

      int main()
      std::vector<std::unordered_map<int, std::unique_ptr<int>>> vec;
      vec.reserve(1);



      Live demo on GodBolt: https://godbolt.org/z/VApPkH.




      Another example:



      #include <set>
      #include <vector>

      struct NonCopyable
      NonCopyable(const NonCopyable&) = delete;
      NonCopyable(NonCopyable&&) noexcept = default;
      ;

      int main()
      std::vector<std::set<NonCopyable>> vec;
      vec.reserve(1);






      share|improve this answer
























        up vote
        3
        down vote










        up vote
        3
        down vote









        I believe this is a bug, since the same error can be triggered by the following minimal code:



        #include <memory>
        #include <unordered_map>
        #include <vector>

        int main()
        std::vector<std::unordered_map<int, std::unique_ptr<int>>> vec;
        vec.reserve(1);



        Live demo on GodBolt: https://godbolt.org/z/VApPkH.




        Another example:



        #include <set>
        #include <vector>

        struct NonCopyable
        NonCopyable(const NonCopyable&) = delete;
        NonCopyable(NonCopyable&&) noexcept = default;
        ;

        int main()
        std::vector<std::set<NonCopyable>> vec;
        vec.reserve(1);






        share|improve this answer














        I believe this is a bug, since the same error can be triggered by the following minimal code:



        #include <memory>
        #include <unordered_map>
        #include <vector>

        int main()
        std::vector<std::unordered_map<int, std::unique_ptr<int>>> vec;
        vec.reserve(1);



        Live demo on GodBolt: https://godbolt.org/z/VApPkH.




        Another example:



        #include <set>
        #include <vector>

        struct NonCopyable
        NonCopyable(const NonCopyable&) = delete;
        NonCopyable(NonCopyable&&) noexcept = default;
        ;

        int main()
        std::vector<std::set<NonCopyable>> vec;
        vec.reserve(1);







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited 12 mins ago

























        answered 20 mins ago









        Daniel Langr

        5,9742243




        5,9742243




















            up vote
            2
            down vote













            Let's look at the std::vector source code (I replaced pointer and _Ty with actual types):



            void _Umove_if_noexcept1(Node* First, Node* Last, Node* Dest, true_type)
            // move [First, Last) to raw Dest, using allocator
            _Uninitialized_move(First, Last, Dest, this->_Getal());


            void _Umove_if_noexcept1(Node* First, Node* Last, Node* Dest, false_type)
            // copy [First, Last) to raw Dest, using allocator
            _Uninitialized_copy(First, Last, Dest, this->_Getal());


            void _Umove_if_noexcept(Node* First, Node* Last, Node* Dest)
            // move_if_noexcept [First, Last) to raw Dest, using allocator
            _Umove_if_noexcept1(First, Last, Dest,
            bool_constant<disjunction_v<is_nothrow_move_constructible<Node>, negation<is_copy_constructible<Node>>>>);



            If Node is no-throw move-constructible or is not copy-constructible, _Uninitialized_move is called. If Node is not no-throw move-constructible and is copy-constructible, _Uninitialized_copy is called.



            The problem is that the type trait std::is_copy_constructible is std::true_type for Node if you do not declare a move constructor explicitly. This declaration makes copy-constructor deleted.






            share|improve this answer


















            • 1




              Im wondering as to why the issue is not seen with clang or gcc ?
              – darune
              1 hour ago






            • 1




              @darune, the dumb answer is because gcc's and clang's implementations do not rely on std::is_copy_constructible in this particular piece of code. I don't have a better answer now.
              – Evg
              1 hour ago










            • If i understand you correctly that code is in the MSVC vector implementation (?) and isn't that a bug in this case ? It does feel like like a bug, because invoking the move constructor directly does compile fine.
              – darune
              1 hour ago











            • @darune, yes, the code in my answer is directly from MSVC STL implementation. I agree that it feels like a bug.
              – Evg
              38 mins ago














            up vote
            2
            down vote













            Let's look at the std::vector source code (I replaced pointer and _Ty with actual types):



            void _Umove_if_noexcept1(Node* First, Node* Last, Node* Dest, true_type)
            // move [First, Last) to raw Dest, using allocator
            _Uninitialized_move(First, Last, Dest, this->_Getal());


            void _Umove_if_noexcept1(Node* First, Node* Last, Node* Dest, false_type)
            // copy [First, Last) to raw Dest, using allocator
            _Uninitialized_copy(First, Last, Dest, this->_Getal());


            void _Umove_if_noexcept(Node* First, Node* Last, Node* Dest)
            // move_if_noexcept [First, Last) to raw Dest, using allocator
            _Umove_if_noexcept1(First, Last, Dest,
            bool_constant<disjunction_v<is_nothrow_move_constructible<Node>, negation<is_copy_constructible<Node>>>>);



            If Node is no-throw move-constructible or is not copy-constructible, _Uninitialized_move is called. If Node is not no-throw move-constructible and is copy-constructible, _Uninitialized_copy is called.



            The problem is that the type trait std::is_copy_constructible is std::true_type for Node if you do not declare a move constructor explicitly. This declaration makes copy-constructor deleted.






            share|improve this answer


















            • 1




              Im wondering as to why the issue is not seen with clang or gcc ?
              – darune
              1 hour ago






            • 1




              @darune, the dumb answer is because gcc's and clang's implementations do not rely on std::is_copy_constructible in this particular piece of code. I don't have a better answer now.
              – Evg
              1 hour ago










            • If i understand you correctly that code is in the MSVC vector implementation (?) and isn't that a bug in this case ? It does feel like like a bug, because invoking the move constructor directly does compile fine.
              – darune
              1 hour ago











            • @darune, yes, the code in my answer is directly from MSVC STL implementation. I agree that it feels like a bug.
              – Evg
              38 mins ago












            up vote
            2
            down vote










            up vote
            2
            down vote









            Let's look at the std::vector source code (I replaced pointer and _Ty with actual types):



            void _Umove_if_noexcept1(Node* First, Node* Last, Node* Dest, true_type)
            // move [First, Last) to raw Dest, using allocator
            _Uninitialized_move(First, Last, Dest, this->_Getal());


            void _Umove_if_noexcept1(Node* First, Node* Last, Node* Dest, false_type)
            // copy [First, Last) to raw Dest, using allocator
            _Uninitialized_copy(First, Last, Dest, this->_Getal());


            void _Umove_if_noexcept(Node* First, Node* Last, Node* Dest)
            // move_if_noexcept [First, Last) to raw Dest, using allocator
            _Umove_if_noexcept1(First, Last, Dest,
            bool_constant<disjunction_v<is_nothrow_move_constructible<Node>, negation<is_copy_constructible<Node>>>>);



            If Node is no-throw move-constructible or is not copy-constructible, _Uninitialized_move is called. If Node is not no-throw move-constructible and is copy-constructible, _Uninitialized_copy is called.



            The problem is that the type trait std::is_copy_constructible is std::true_type for Node if you do not declare a move constructor explicitly. This declaration makes copy-constructor deleted.






            share|improve this answer














            Let's look at the std::vector source code (I replaced pointer and _Ty with actual types):



            void _Umove_if_noexcept1(Node* First, Node* Last, Node* Dest, true_type)
            // move [First, Last) to raw Dest, using allocator
            _Uninitialized_move(First, Last, Dest, this->_Getal());


            void _Umove_if_noexcept1(Node* First, Node* Last, Node* Dest, false_type)
            // copy [First, Last) to raw Dest, using allocator
            _Uninitialized_copy(First, Last, Dest, this->_Getal());


            void _Umove_if_noexcept(Node* First, Node* Last, Node* Dest)
            // move_if_noexcept [First, Last) to raw Dest, using allocator
            _Umove_if_noexcept1(First, Last, Dest,
            bool_constant<disjunction_v<is_nothrow_move_constructible<Node>, negation<is_copy_constructible<Node>>>>);



            If Node is no-throw move-constructible or is not copy-constructible, _Uninitialized_move is called. If Node is not no-throw move-constructible and is copy-constructible, _Uninitialized_copy is called.



            The problem is that the type trait std::is_copy_constructible is std::true_type for Node if you do not declare a move constructor explicitly. This declaration makes copy-constructor deleted.







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited 1 hour ago

























            answered 1 hour ago









            Evg

            3,41811334




            3,41811334







            • 1




              Im wondering as to why the issue is not seen with clang or gcc ?
              – darune
              1 hour ago






            • 1




              @darune, the dumb answer is because gcc's and clang's implementations do not rely on std::is_copy_constructible in this particular piece of code. I don't have a better answer now.
              – Evg
              1 hour ago










            • If i understand you correctly that code is in the MSVC vector implementation (?) and isn't that a bug in this case ? It does feel like like a bug, because invoking the move constructor directly does compile fine.
              – darune
              1 hour ago











            • @darune, yes, the code in my answer is directly from MSVC STL implementation. I agree that it feels like a bug.
              – Evg
              38 mins ago












            • 1




              Im wondering as to why the issue is not seen with clang or gcc ?
              – darune
              1 hour ago






            • 1




              @darune, the dumb answer is because gcc's and clang's implementations do not rely on std::is_copy_constructible in this particular piece of code. I don't have a better answer now.
              – Evg
              1 hour ago










            • If i understand you correctly that code is in the MSVC vector implementation (?) and isn't that a bug in this case ? It does feel like like a bug, because invoking the move constructor directly does compile fine.
              – darune
              1 hour ago











            • @darune, yes, the code in my answer is directly from MSVC STL implementation. I agree that it feels like a bug.
              – Evg
              38 mins ago







            1




            1




            Im wondering as to why the issue is not seen with clang or gcc ?
            – darune
            1 hour ago




            Im wondering as to why the issue is not seen with clang or gcc ?
            – darune
            1 hour ago




            1




            1




            @darune, the dumb answer is because gcc's and clang's implementations do not rely on std::is_copy_constructible in this particular piece of code. I don't have a better answer now.
            – Evg
            1 hour ago




            @darune, the dumb answer is because gcc's and clang's implementations do not rely on std::is_copy_constructible in this particular piece of code. I don't have a better answer now.
            – Evg
            1 hour ago












            If i understand you correctly that code is in the MSVC vector implementation (?) and isn't that a bug in this case ? It does feel like like a bug, because invoking the move constructor directly does compile fine.
            – darune
            1 hour ago





            If i understand you correctly that code is in the MSVC vector implementation (?) and isn't that a bug in this case ? It does feel like like a bug, because invoking the move constructor directly does compile fine.
            – darune
            1 hour ago













            @darune, yes, the code in my answer is directly from MSVC STL implementation. I agree that it feels like a bug.
            – Evg
            38 mins ago




            @darune, yes, the code in my answer is directly from MSVC STL implementation. I agree that it feels like a bug.
            – Evg
            38 mins ago










            finn is a new contributor. Be nice, and check out our Code of Conduct.









             

            draft saved


            draft discarded


















            finn is a new contributor. Be nice, and check out our Code of Conduct.












            finn is a new contributor. Be nice, and check out our Code of Conduct.











            finn is a new contributor. Be nice, and check out our Code of Conduct.













             


            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53168836%2fdoes-vs2017-need-explict-move-constructor-declaration%23new-answer', 'question_page');

            );

            Post as a guest













































































            Comments

            Popular posts from this blog

            What does second last employer means? [closed]

            List of Gilmore Girls characters

            Confectionery