{"id":187,"date":"2019-01-10T21:32:01","date_gmt":"2019-01-11T05:32:01","guid":{"rendered":"http:\/\/35.243.195.209\/?p=187"},"modified":"2019-01-10T21:32:01","modified_gmt":"2019-01-11T05:32:01","slug":"moving-a-return-value-is-easy","status":"publish","type":"post","link":"https:\/\/nanzhou.cc\/index.php\/2019\/01\/10\/moving-a-return-value-is-easy\/","title":{"rendered":"Moving a Return Value is Easy"},"content":{"rendered":"<h2>Summary<\/h2>\n<p>In this post, we will discuss rvalue references and move semantics in C++11.<\/p>\n<h2>Details<\/h2>\n<p>Rvalue references and move semantics can be very complex, see <a href=\"http:\/\/thbecker.net\/articles\/rvalue_references\/section_01.html\">this article<\/a>. But the truth is that: <strong>the simplest is the best<\/strong>. It starts with three examples of returning values from functions. Read them and ask yourself which of them is going to do no vector copy.<\/p>\n<h4>First example<\/h4>\n<pre><code class=\"c\">std::vector&lt;int&gt; return_vector(void) {\n    std::vector&lt;int&gt; tmp {1,2,3,4,5};\n    return tmp;\n}\n\nstd::vector&lt;int&gt; &amp;&amp;rval_ref = return_vector();\n<\/code><\/pre>\n<p>It returns a temporary caught by <code>rval_ref<\/code> whose life extended beyond the <code>rval_ref<\/code> definition. We can use it as if you had caught it by value.<\/p>\n<h4>Second example<\/h4>\n<pre><code class=\"c\">std::vector&lt;int&gt;&amp;&amp; return_vector(void) {\n    std::vector&lt;int&gt; tmp {1,2,3,4,5};\n    return std::move(tmp);\n}\n\nstd::vector&lt;int&gt; &amp;&amp;rval_ref = return_vector();\n<\/code><\/pre>\n<p>Actually it will cause a run time error. Because <code>rval_ref<\/code> now holds a reference to the destructed tmp inside the function. The following codes crashes.<\/p>\n<pre><code class=\"c\">std::vector&lt;int&gt; &amp;&amp;rval_ref = return_vector();\ncout &lt;&lt; rval_ref[0] &lt;&lt; endl;\nrval_ref[0] = 2;\ncout &lt;&lt; rval_ref[0] &lt;&lt; endl; \/\/ Process finished with exit code 11\n<\/code><\/pre>\n<h4>Third example<\/h4>\n<pre><code class=\"c\">std::vector&lt;int&gt; return_vector(void) {\n    std::vector&lt;int&gt; tmp {1,2,3,4,5};\n    return std::move(tmp);\n}\nstd::vector&lt;int&gt; &amp;&amp;rval_ref = return_vector();\n<\/code><\/pre>\n<p>This example is roughly equivalent to the first. Actually the <code>std::move<\/code> on <code>tmp<\/code> is unnecessary and even can be inhibit return value optimization.<\/p>\n<h4>Best way<\/h4>\n<p>The following simple code is the best way to get value from functions.<\/p>\n<pre><code class=\"c\">std::vector&lt;int&gt; return_vector(void)\n{\n    std::vector&lt;int&gt; tmp {1,2,3,4,5};\n    return tmp;\n}\n\nstd::vector&lt;int&gt; rval_ref = return_vector();\n<\/code><\/pre>\n<p>It will actually do<br \/>\n1. RVO (no copy, no move) by default;<br \/>\n2. move constructor if RVO is not possible;<br \/>\n3. copy constructor if RVO is not possible and the returned type did not have a move constructor.<br \/>\nThanks to the compilers, &#8220;often the cleanest, simplest code that doesn\u2019t even mention <code>move<\/code> or <code>&amp;&amp;<\/code> anywhere is just what you want \u2013 that\u2019s C++11, clean, safe, and faster than ever&#8221;.<\/p>\n<h4>RVO<\/h4>\n<p>Return value optimization, aka RVO, is a compiler optimization technique that allows the compiler to construct the return value of a function at the call site. The technique is also named &#8220;elision&#8221;. C++98\/03 standard doesn\u2019t require the compiler to provide RVO optimization, but most popular C++ compilers contain this optimization technique, such as <code>IBM XL C++ compiler<\/code>, <code>GCC<\/code> and <code>Clang<\/code> . This optimization technique is included in the C++11 standard due to its prevalence. As defined in Section 12.8 in the C++11 standard, the name of the technique is &#8220;copy elision&#8221;.<\/p>\n<h2>Reference<\/h2>\n<ol>\n<li><a href=\"https:\/\/isocpp.org\/blog\/2013\/02\/no-really-moving-a-return-value-is-easy-stackoverflow\">isocpp.org<\/a><\/li>\n<li><a href=\"https:\/\/stackoverflow.com\/questions\/4986673\/c11-rvalues-and-move-semantics-confusion-return-statement\/4986802#4986802\">Q&amp;A in stack-overflow<\/a><\/li>\n<\/ol>\n","protected":false},"excerpt":{"rendered":"<p>Summary In this post, we will discuss rvalue references and move semantics in C++11. Details Rvalue references and move semantics can be very complex, see this article. But the truth is that: the simplest is the best. It starts with three examples of returning values from functions. Read them and ask yourself which of them&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[6,5],"tags":[],"class_list":["post-187","post","type-post","status-publish","format-standard","hentry","category-c","category-proglang"],"_links":{"self":[{"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/posts\/187","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/comments?post=187"}],"version-history":[{"count":3,"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/posts\/187\/revisions"}],"predecessor-version":[{"id":190,"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/posts\/187\/revisions\/190"}],"wp:attachment":[{"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/media?parent=187"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/categories?post=187"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/tags?post=187"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}