{"id":103452,"date":"2020-02-19T07:00:00","date_gmt":"2020-02-19T15:00:00","guid":{"rendered":"http:\/\/devblogs.microsoft.com\/oldnewthing\/?p=103452"},"modified":"2020-02-19T07:10:55","modified_gmt":"2020-02-19T15:10:55","slug":"20200219-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20200219-00\/?p=103452","title":{"rendered":"If you plan on keeping the parameter anyway, then there&#8217;s no need to have separate <CODE>T const&amp;<\/CODE> and <CODE>T&amp;&amp;<\/CODE> overloads"},"content":{"rendered":"<p>Suppose you have a function that takes a <code>std::vector<\/code> and it wants to take ownership of the vector. You might decide to write two overloads:<\/p>\n<pre>class Widget\r\n{\r\npublic:\r\n  <span style=\"color: blue;\">void SetValue(std::vector&lt;int&gt; const&amp; value)<\/span>\r\n  {\r\n    m_values = values;\r\n  }\r\n\r\n  <span style=\"color: blue;\">void SetValue(std::vector&lt;int&gt;&amp;&amp; value)<\/span>\r\n  {\r\n    m_values = std::move(values);\r\n  }\r\nprivate:\r\n  std::vector&lt;int&gt; m_values;\r\n};\r\n<\/pre>\n<p>If the caller passes a read-only lvalue reference, then you have to copy the vector. But if the caller passes an rvalue reference, then you can steal the vector by moving it into the <code>m_values<\/code>.<\/p>\n<p>But really, the extra overload is just duplicated code for no real purpose. You&#8217;re going to keep the object either way, so just make the caller provide it in a form you can keep: Pass it by value.<\/p>\n<pre>class Widget\r\n{\r\npublic:\r\n  <span style=\"color: blue;\">void SetValue(std::vector&lt;int&gt; value)<\/span>\r\n  {\r\n    m_values = std::move(values);\r\n  }\r\n\r\nprivate:\r\n  std::vector&lt;int&gt; m_values;\r\n};\r\n<\/pre>\n<p>If the caller tries to pass an lvalue reference, then the compiler will use the copy constructor to create the inbound <code>value<\/code> parameter, which you then move into <code>m_values<\/code>.<\/p>\n<p>If the caller tries to pass an rvalue reference, then the compiler will move it into the inbound <code>value<\/code> parameter, which you then move onward into <code>m_values<\/code>.<\/p>\n<p>You get the same result without needing any overloads. Lvalues are copied and rvalues are moved.\u00b9<\/p>\n<p><b>Related reading<\/b>: <a href=\"https:\/\/cpptruths.blogspot.com\/2012\/03\/rvalue-references-in-constructor-when.html\"> Rvalue references in constructor: when less is more<\/a>.<\/p>\n<p>\u00b9 Now, there is a bit of extra cost associated with this simplification: The copying or moving into the parameter is done at the call site, and the formal parameter now needs to be destructed. But you avoid having to write two versions of every function, and I think that simplification is worth it. (Besides, the compiler can often optimize the move.)<\/p>\n","protected":false},"excerpt":{"rendered":"<p>You can just take it by value and move it out.<\/p>\n","protected":false},"author":1069,"featured_media":111744,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[25],"class_list":["post-103452","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>You can just take it by value and move it out.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/103452","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/users\/1069"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/comments?post=103452"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/103452\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media\/111744"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media?parent=103452"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=103452"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=103452"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}