{"id":1503,"date":"2016-02-25T23:02:48","date_gmt":"2016-02-25T22:02:48","guid":{"rendered":"http:\/\/netrix.org.pl\/?p=1503"},"modified":"2016-02-25T23:02:48","modified_gmt":"2016-02-25T22:02:48","slug":"defined-and-not-defined-constructor-in-c","status":"publish","type":"post","link":"https:\/\/netrix.org.pl\/index.php\/2016\/02\/25\/defined-and-not-defined-constructor-in-c\/","title":{"rendered":"Defined and not defined constructor in C++"},"content":{"rendered":"<p>C++ is a pretty interesting language because of different quirks that it has. One of such things is the fact that there is a difference between defined constructor, not defined constructor and deleted constructor, especially move constructor.<\/p>\n<p>Consider following code:<\/p>\n<pre lang=\"cpp\" line=\"1\">\r\n#include <iostream>\r\n\r\nstruct ExplicitMoveConstructor\r\n{\r\n    ExplicitMoveConstructor()\r\n    {\r\n        std::cout << \"Default constructor\" << std::endl;\r\n    }\r\n\r\n    ExplicitMoveConstructor(ExplicitMoveConstructor const&#038; src)\r\n    {\r\n        std::cout << \"Copy constructor\" << std::endl;\r\n    }\r\n\r\n    ExplicitMoveConstructor(ExplicitMoveConstructor &#038;&#038; src)\r\n    {\r\n        std::cout << \"Move constructor\" << std::endl;\r\n    }\r\n};\r\n\r\nstruct DeletedMoveConstructor\r\n{\r\n    DeletedMoveConstructor()\r\n    {\r\n        std::cout << \"Default constructor\" << std::endl;\r\n    }\r\n\r\n    DeletedMoveConstructor(DeletedMoveConstructor const&#038; src)\r\n    {\r\n        std::cout << \"Copy constructor\" << std::endl;\r\n    }\r\n\r\n    DeletedMoveConstructor(DeletedMoveConstructor &#038;&#038; src) = delete;\r\n};\r\n\r\nstruct NotDefinedMoveConstructor\r\n{\r\n    NotDefinedMoveConstructor()\r\n    {\r\n        std::cout << \"Default constructor\" << std::endl;\r\n    }\r\n\r\n    NotDefinedMoveConstructor(NotDefinedMoveConstructor const&#038; src)\r\n    {\r\n        std::cout << \"Copy constructor\" << std::endl;\r\n    }\r\n};\r\n\r\nauto returnExplicitMoveConstructorClass()\r\n{\r\n    ExplicitMoveConstructor cm;\r\n    return cm;\r\n}\r\n\r\nauto returnDeletedMoveConstructorClass()\r\n{\r\n    DeletedMoveConstructor cm;\r\n    return cm;\r\n}\r\n\r\nauto returnNotDefinedMoveConstructorClass()\r\n{\r\n    NotDefinedMoveConstructor cm;\r\n    return cm;\r\n}\r\n\r\nint main()\r\n{\r\n    auto first = returnExplicitMoveConstructorClass();\r\n    auto second = returnDeletedMoveConstructorClass();\r\n    auto third = returnNotDefinedMoveConstructorClass();\r\n    return 0;\r\n}\r\n<\/pre>\n<p>The presented code does not compile when trying to do so with following command:<\/p>\n<pre lang=\"text\">\r\nclang++ constructor.cpp --std=c++14\r\n<\/pre>\n<p>The error code is as follows:<\/p>\n<pre lang=\"text\">\r\nconstructor.cpp:70:7: error: call to deleted constructor of 'DeletedMoveConstructor'\r\n        auto second = returnDeletedMoveConstructorClass();\r\n             ^        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\r\nconstructor.cpp:33:2: note: 'DeletedMoveConstructor' has been explicitly marked deleted here\r\n        DeletedMoveConstructor(DeletedMoveConstructor && src) = delete;\r\n        ^\r\n1 error generated.\r\n<\/pre>\n<p>The error from the compiler says that the move constructor was called but it is marked as deleted. If compiled with g++ it's pretty much the same.  <\/p>\n<p>Conclusions from this are two. The first one is that the deleted constructor is also a declared constructor so the compiler will use it as if it was defined by the user. The second one is that the value returned from function is returned by utilizing move semantic when move constructor is declared, even if it is deleted. <\/p>\n<p>The explaination for this turns out to be quite simple. As written in <a href=\"https:\/\/stackoverflow.com\/questions\/29164188\/does-returning-a-local-object-require-move-semantics\/29164221#29164221\" target=\"_blank\"><strong>this<\/strong><\/a> post on Stack Overflow, this is the intended behaviour of overload resolution. Since declared, the move constructor is the best match for value returned from function which is an r-value.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>C++ is a pretty interesting language because of different quirks that it has. One of such things is the fact that there is a difference between defined constructor, not defined constructor and deleted constructor, especially move constructor. Consider following code: #include struct ExplicitMoveConstructor { ExplicitMoveConstructor() { std::cout<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[12],"tags":[],"_links":{"self":[{"href":"https:\/\/netrix.org.pl\/index.php\/wp-json\/wp\/v2\/posts\/1503"}],"collection":[{"href":"https:\/\/netrix.org.pl\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/netrix.org.pl\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/netrix.org.pl\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/netrix.org.pl\/index.php\/wp-json\/wp\/v2\/comments?post=1503"}],"version-history":[{"count":18,"href":"https:\/\/netrix.org.pl\/index.php\/wp-json\/wp\/v2\/posts\/1503\/revisions"}],"predecessor-version":[{"id":1521,"href":"https:\/\/netrix.org.pl\/index.php\/wp-json\/wp\/v2\/posts\/1503\/revisions\/1521"}],"wp:attachment":[{"href":"https:\/\/netrix.org.pl\/index.php\/wp-json\/wp\/v2\/media?parent=1503"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/netrix.org.pl\/index.php\/wp-json\/wp\/v2\/categories?post=1503"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/netrix.org.pl\/index.php\/wp-json\/wp\/v2\/tags?post=1503"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}