{"id":4643,"date":"2009-02-03T12:27:00","date_gmt":"2009-02-03T12:27:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/vcblog\/2009\/02\/03\/rvalue-references-c0x-features-in-vc10-part-2\/"},"modified":"2022-01-19T19:07:45","modified_gmt":"2022-01-19T19:07:45","slug":"rvalue-references-c0x-features-in-vc10-part-2","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/cppblog\/rvalue-references-c0x-features-in-vc10-part-2\/","title":{"rendered":"Rvalue References: C++0x Features in VC10, Part 2"},"content":{"rendered":"<p class=\"MsoNormal\"><a href=\"http:\/\/blogs.msdn.com\/vcblog\/archive\/2008\/10\/28\/lambdas-auto-and-static-assert-c-0x-features-in-vc10-part-1.aspx\"><span style=\"color: #0000ff; font-family: Verdana; font-size: medium;\">Part 1<\/span><\/a><span style=\"font-family: Verdana; font-size: medium;\"> of this series covered <b>lambdas<\/b>, <b>auto<\/b>, and <b>static_assert<\/b>.<\/span><\/p>\n<p><span style=\"font-family: Verdana; font-size: medium;\">\u00a0<\/span><\/p>\n<p class=\"MsoNormal\"><span style=\"font-family: Verdana; font-size: medium;\">Today, I&#8217;m going to talk about <b>rvalue references<\/b>, which enable two different things: <b>move semantics<\/b> and <b>perfect forwarding<\/b>.\u00a0 This post will be long, because I&#8217;m going to explain how rvalue references work in great detail.\u00a0 They&#8217;re initially very confusing because they distinguish lvalues from rvalues, which very few C++98\/03 programmers are extensively familiar with.<\/span><\/p>\n<p><span style=\"font-family: Verdana; font-size: medium;\">\u00a0<\/span><\/p>\n<p class=\"MsoNormal\"><span style=\"font-family: Verdana; font-size: medium;\">Fear not, for using rvalue references is easy, much easier than it initially sounds.\u00a0 Implementing either move semantics or perfect forwarding in your own code boils down to following simple patterns, which I will demonstrate.\u00a0 And it&#8217;s definitely worth learning how to use rvalue references, as move semantics can produce <i>order of magnitude<\/i> performance improvements, and perfect forwarding makes writing highly generic code very easy.<\/span><\/p>\n<p><span style=\"font-family: Verdana; font-size: medium;\">\u00a0<\/span><\/p>\n<p><span style=\"font-family: Verdana; font-size: medium;\">\u00a0<\/span><\/p>\n<p class=\"MsoNormal\"><b><span style=\"font-size: medium;\"><span style=\"font-family: Verdana;\">lvalues and rvalues in C++98\/03<\/span><\/span><\/b><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-family: Verdana; font-size: medium;\">\u00a0<\/span><\/p>\n<p class=\"MsoNormal\"><span style=\"font-family: Verdana; font-size: medium;\">In order to understand rvalue references in C++0x, you must first understand lvalues and rvalues in C++98\/03.<\/span><\/p>\n<p><span style=\"font-family: Verdana; font-size: medium;\">\u00a0<\/span><\/p>\n<p class=\"MsoNormal\"><span style=\"font-family: Verdana; font-size: medium;\">The terminology of &#8220;lvalues&#8221; and &#8220;rvalues&#8221; is confusing because their history is confusing.\u00a0 (By the way, they&#8217;re just pronounced as &#8220;L values&#8221; and &#8220;R values&#8221;, although they&#8217;re written as single words.)\u00a0 These concepts originally came from C, and then were elaborated upon by C++.\u00a0 To save time, I&#8217;ll skip over their history, including why they&#8217;re called &#8220;lvalues&#8221; and &#8220;rvalues&#8221;, and I&#8217;ll go directly to how they work in C++98\/03.\u00a0 (Okay, it&#8217;s not a big secret: &#8220;L&#8221; stands for &#8220;left&#8221; and &#8220;R&#8221; stands for &#8220;right&#8221;.\u00a0 But the concepts have evolved since the names were chosen, and the names aren&#8217;t very accurate anymore.\u00a0 Instead of going through the whole history lesson, you can consider the names to be arbitrary like &#8220;up quark&#8221; and &#8220;down quark&#8221;, and you won&#8217;t lose anything.)<\/span><\/p>\n<p><span style=\"font-family: Verdana; font-size: medium;\">\u00a0<\/span><\/p>\n<p class=\"MsoNormal\"><span style=\"font-family: Verdana; font-size: medium;\">C++03 3.10\/1 says: &#8220;Every expression is either an <i>lvalue<\/i> or an <i>rvalue<\/i>.&#8221;\u00a0 It&#8217;s important to remember that lvalueness versus rvalueness is a property of expressions, not of objects.<\/span><\/p>\n<p><span style=\"font-family: Verdana; font-size: medium;\">\u00a0<\/span><\/p>\n<p class=\"MsoNormal\"><span style=\"font-size: medium;\"><span style=\"font-family: Verdana;\">Lvalues name objects that persist beyond a single expression.\u00a0 For example, <\/span>obj<span style=\"font-family: Verdana;\"> , <\/span>*ptr<span style=\"font-family: Verdana;\"> , <\/span>ptr[index]<span style=\"font-family: Verdana;\"> , and <\/span>++x<span style=\"font-family: Verdana;\"> are all lvalues.<\/span><\/span><\/p>\n<p><span style=\"font-family: Verdana; font-size: medium;\">\u00a0<\/span><\/p>\n<p class=\"MsoNormal\"><span style=\"font-size: medium;\"><span style=\"font-family: Verdana;\">Rvalues are temporaries that evaporate at the end of the full-expression in which they live (&#8220;at the semicolon&#8221;).\u00a0 For example, <\/span>1729<span style=\"font-family: Verdana;\"> , <\/span>x + y<span style=\"font-family: Verdana;\"> , <\/span>std::string(&#8220;meow&#8221;)<span style=\"font-family: Verdana;\"> , and <\/span>x++<span style=\"font-family: Verdana;\"> are all rvalues.<\/span><\/span><\/p>\n<p><span style=\"font-family: Verdana; font-size: medium;\">\u00a0<\/span><\/p>\n<p class=\"MsoNormal\"><span style=\"font-size: medium;\"><span style=\"font-family: Verdana;\">Notice the difference between <\/span>++x<span style=\"font-family: Verdana;\"> and <\/span>x++<span style=\"font-family: Verdana;\"> .\u00a0 If we have <\/span>int x = 0;<span style=\"font-family: Verdana;\"> then the expression <\/span>x<span style=\"font-family: Verdana;\"> is an lvalue, as it names a persistent object.\u00a0 The expression <\/span>++x<span style=\"font-family: Verdana;\"> is also an lvalue.\u00a0 It modifies and then names the persistent object.\u00a0 However, the expression <\/span>x++<span style=\"font-family: Verdana;\"> is an rvalue.\u00a0 It copies the original value of the persistent object, modifies the persistent object, and then returns the copy.\u00a0 This copy is a temporary.\u00a0 Both <\/span>++x<span style=\"font-family: Verdana;\"> and <\/span>x++<span style=\"font-family: Verdana;\"> increment <\/span>x<span style=\"font-family: Verdana;\">, but <\/span>++x<span style=\"font-family: Verdana;\"> returns the persistent object itself, while <\/span>x++<span style=\"font-family: Verdana;\"> returns a temporary copy.\u00a0 That&#8217;s why <\/span>++x<span style=\"font-family: Verdana;\"> is an lvalue, while <\/span>x++<span style=\"font-family: Verdana;\"> is an rvalue.\u00a0 Lvalueness versus rvalueness doesn&#8217;t care about what an expression <i>does<\/i>, it cares about what an expression <i>names<\/i> (something persistent or something temporary).<\/span><\/span><\/p>\n<p><span style=\"font-family: Verdana; font-size: medium;\">\u00a0<\/span><\/p>\n<p class=\"MsoNormal\"><span style=\"font-size: medium;\"><span style=\"font-family: Verdana;\">If you want to build up intuition for this, another way to determine whether an expression is an lvalue is to ask &#8220;can I take its address?&#8221;.\u00a0 If you can, it&#8217;s an lvalue.\u00a0 If you can&#8217;t, it&#8217;s an rvalue.\u00a0 For example, <\/span>&amp;obj<span style=\"font-family: Verdana;\"> , <\/span>&amp;*ptr<span style=\"font-family: Verdana;\"> , <\/span>&amp;ptr[index]<span style=\"font-family: Verdana;\"> , and <\/span>&amp;++x<span style=\"font-family: Verdana;\"> are all valid (even though some of those expressions are silly), while <\/span>&amp;1729<span style=\"font-family: Verdana;\"> , <\/span>&amp;(x + y)<span style=\"font-family: Verdana;\"> , <\/span>&amp;std::string(&#8220;meow&#8221;)<span style=\"font-family: Verdana;\"> , and <\/span>&amp;x++<span style=\"font-family: Verdana;\"> are all invalid.\u00a0 Why does this work?&amp;nbs\np; The address-of operator requires that its &#8220;operand shall be an lvalue&#8221; (C++03 5.3.1\/2).\u00a0 Why does it require that?\u00a0 Taking the address of a persistent object is fine, but taking the address of a temporary would be extremely dangerous, because temporaries evaporate quickly.<\/span><\/span><\/p>\n<p><span style=\"font-family: Verdana; font-size: medium;\">\u00a0<\/span><\/p>\n<p class=\"MsoNormal\"><span style=\"font-size: medium;\"><span style=\"font-family: Verdana;\">The preceding examples ignore operator overloading, which is convenient syntax for a function call.\u00a0 &#8220;A function call is an lvalue if and only if the result type is a reference.&#8221; (C++03 5.2.2\/10)\u00a0 Therefore, given <\/span>vector&lt;int&gt; v(10, 1729);<span style=\"font-family: Verdana;\"> , <\/span>v[0]<span style=\"font-family: Verdana;\"> is an lvalue because <\/span>operator[]()<span style=\"font-family: Verdana;\"> returns <\/span>int&amp;<span style=\"font-family: Verdana;\"> (and <\/span>&amp;v[0]<span style=\"font-family: Verdana;\"> is valid and useful), while given <\/span>string s(&#8220;foo&#8221;);<span style=\"font-family: Verdana;\"> and <\/span>string t(&#8220;bar&#8221;);<span style=\"font-family: Verdana;\"> , <\/span>s + t<span style=\"font-family: Verdana;\"> is an rvalue because <\/span>operator+()<span style=\"font-family: Verdana;\"> returns <\/span>string<span style=\"font-family: Verdana;\"> (and <\/span>&amp;(s + t)<span style=\"font-family: Verdana;\"> is invalid).<\/span><\/span><\/p>\n<p><span style=\"font-family: Verdana; font-size: medium;\">\u00a0<\/span><\/p>\n<p class=\"MsoNormal\"><span style=\"font-size: medium;\"><span style=\"font-family: Verdana;\">Both lvalues and rvalues can be either modifiable (non-<\/span>const<span style=\"font-family: Verdana;\">) or non-modifiable (<\/span>const<span style=\"font-family: Verdana;\">).\u00a0 Here are examples:<\/span><\/span><\/p>\n<p><span style=\"font-family: Verdana; font-size: medium;\">\u00a0<\/span><\/p>\n<p class=\"MsoNormal\"><span style=\"font-size: medium;\">string one(&#8220;cute&#8221;);<\/span><\/p>\n<p>&nbsp;<\/p>\n<p class=\"MsoNormal\"><span style=\"font-size: medium;\">const string two(&#8220;fluffy&#8221;);<\/span><\/p>\n<p>&nbsp;<\/p>\n<p class=\"MsoNormal\"><span style=\"font-size: medium;\">string three() { return &#8220;kittens&#8221;; }<\/span><\/p>\n<p>&nbsp;<\/p>\n<p class=\"MsoNormal\"><span style=\"font-size: medium;\">const string four() { return &#8220;are an essential part of a healthy diet&#8221;; }<\/span><\/p>\n<p>&nbsp;<\/p>\n<p class=\"MsoNormal\">\n<p><span style=\"font-size: medium;\">\u00a0<\/span><\/p>\n<p>&nbsp;<\/p>\n<p class=\"MsoNormal\"><span style=\"font-size: medium;\">one;\u00a0\u00a0\u00a0\u00a0 \/\/ modifiable lvalue<\/span><\/p>\n<p>&nbsp;<\/p>\n<p class=\"MsoNormal\"><span style=\"font-size: medium;\">two;\u00a0\u00a0\u00a0\u00a0 \/\/ const lvalue<\/span><\/p>\n<p>&nbsp;<\/p>\n<p class=\"MsoNormal\"><span style=\"font-size: medium;\">three(); \/\/ modifiable rvalue<\/span><\/p>\n<p>&nbsp;<\/p>\n<p class=\"MsoNormal\"><span style=\"font-size: medium;\">four();\u00a0 \/\/ const rvalue<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-family: Verdana; font-size: medium;\">\u00a0<\/span><\/p>\n<p class=\"MsoNormal\"><span style=\"font-size: medium;\">Type&amp;<span style=\"font-family: Verdana;\"> binds to modifiable lvalues (and can be used to observe and mutate them).\u00a0 It can&#8217;t bind to <\/span>const<span style=\"font-family: Verdana;\"> lvalues, as that would violate <\/span>const<span style=\"font-family: Verdana;\"> correctness.\u00a0 It can&#8217;t bind to modifiable rvalues, as that would be extremely dangerous.\u00a0 Accidentally modifying temporaries, only to have the temporaries evaporate along with your modifications, would lead to subtle and obnoxious bugs, so C++ rightly prohibits this.\u00a0 (I should mention that VC has an evil extension that allows this, but if you compile with \/W4 , it warns when the evil extension is activated.\u00a0 Usually.)\u00a0 And it can&#8217;t bind to <\/span>const<span style=\"font-family: Verdana;\"> rvalues, as that would be doubly bad.\u00a0 (Careful readers should note that I&#8217;m not talking about template argument deduction here.)<\/span><\/span><\/p>\n<p><span style=\"font-family: Verdana; font-size: medium;\">\u00a0<\/span><\/p>\n<p class=\"MsoNormal\"><span style=\"font-size: medium;\">const Type&amp;<span style=\"font-family: Verdana;\"> binds to everything: modifiable lvalues, <\/span>const<span style=\"font-family: Verdana;\"> lvalues, modifiable rvalues, and <\/span>const<span style=\"font-family: Verdana;\"> rvalues (and can be used to observe them).<\/span><\/span><\/p>\n<p><span style=\"font-family: Verdana; font-size: medium;\">\u00a0<\/span><\/p>\n<p class=\"MsoNormal\"><span style=\"font-size: medium;\"><span style=\"font-family: Verdana;\">A reference is a name, so a reference bound to an rvalue is itself an lvalue (yes, L).\u00a0 (As only a <\/span>const<span style=\"font-family: Verdana;\"> reference can be bound to an rvalue, it will be a <\/span>const<span style=\"font-family: Verdana;\"> lvalue.)\u00a0 This is confusing, and will be an extremely big deal later, so I&#8217;ll explain further.\u00a0 Given the function <\/span>void observe(const string&amp; str)<span style=\"font-family: Verdana;\"> , inside <\/span>observe()<span style=\"font-family: Verdana;\">&#8216;s implementation, <\/span>str<span style=\"font-family: Verdana;\"> is a <\/span>const<span style=\"font-family: Verdana;\"> lvalue, and its address can be taken and used before <\/span>observe()<span style=\"font-family: Verdana;\"> returns.\u00a0 This is true even though <\/span>observe()<span style=\"font-family: Verdana;\"> can be called with rvalues, such as <\/span>three()<span style=\"font-family: Verdana;\"> or <\/span>four()<span style=\"font-family: Verdana;\"> above.\u00a0 <\/span>observe(&#8220;purr&#8221;)<span style=\"font-family: Verdana;\"> can also be called, which constructs a temporary <\/span>string<span style=\"font-family: Verdana;\"> and binds <\/span>str<span style=\"font-family: Verdana;\"> to that temporary.\u00a0 The return values of <\/span>three()<span style=\"font-family: Verdana;\"> and <\/span>four()<span style=\"font-family: Verdana;\"> don&#8217;t have names, so they&#8217;re rvalues, but within <\/span>observe()<span style=\"font-family: Verdana;\">, <\/span>str<span style=\"font-family: Verdana;\"> is a name, so it&#8217;s an lvalue.\u00a0 As I said above, &#8220;lvalueness versus rvalueness is a property of expressions, not of objects&#8221;.\u00a0 Of course, because <\/span>str<span style=\"font-family: Verdana;\"> can be bound to a temporary which will evaporate, its address shouldn&#8217;t be stored anywhere where it could be used after <\/span>observe()<span style=\"font-family: Verdana;\"> returns.<\/span><\/span><\/p>\n<p><span style=\"font-family: Verdana; font-size: medium;\">\u00a0<\/span><\/p>\n<p class=\"MsoNormal\"><span style=\"font-size: medium;\"><span style=\"font-family: Verdana;\">Have you ever bound an rvalue to a <\/span>const<span style=\"font-family: Verdana;\"> reference and then taken its address?\u00a0 Yes, you have!\u00a0 This is what happens when you write a copy assignment operator, <\/span>Foo&amp; operator=(const Foo&amp; other)<span style=\"font-family: Verdana;\"> , with a self-assignment check, <\/span>if (this != &amp;other) { copy stuff; } return *this;<span style=\"font-family: Verdana;\"> , and you copy assign from a temporary, like <\/span>Foo make_foo(); Foo f; f = make_foo();<span style=\"font-family: Verdana;\"> .<\/span><\/span><\/p>\n<p><span style=\"font-family: Verdana; font-size: medium;\">\u00a0<\/span><\/p>\n<p class=\"MsoNormal\"><span style=\"font-size: medium;\"><span style=\"font-family: Verdana;\">At this point, you might ask, &#8220;So what&#8217;s the difference between modifiable rvalues and <\/span>const<span style=\"font-family: Verdana;\"> rvalues?\u00a0 I can&#8217;t bind <\/span>Type&amp;<span style=\"font-family: Verdana;\"> to modifiable rvalues, and I can&#8217;t assign things (etc.) to modifiable rvalues, so can I really modify them?&#8221;\u00a0 This is a very good question!\u00a0 In C++98\/03, the answer is that there&#8217;s a slight difference: non-<\/span>const<span style=\"font-family: Verdana;\"> member functions can be called on modifiable rvalues.\u00a0 C++ doesn&#8217;t want you to accidentally modify temporaries, but directly calling a non-<\/span>const<span style=\"font-family: Verdana;\"> member function on a modifiable rvalue is explicit, so it&#8217;s allowed.\u00a0 In C++0x, the answer changes dramatically, making move semantics possible.<\/span><\/span><\/p>\n<p><span style=\"font-family: Verdana; font-size: medium;\">\u00a0<\/span><\/p>\n<p class=\"MsoNormal\"><span style=\"font-size: medium;\"><span style=\"font-family: Verdana;\">Congratulations!\u00a0 Now you have what I call &#8220;lvalue\/rvalue vision&#8221;, the ability to look at an expression and determine whether it&#8217;s an lvalue or an rvalue.\u00a0 Combined with your &#8220;<\/span>const<span style=\"font-family: Verdana;\"> vision&#8221;, you can precisely reason that given <\/span>void mutate(string&amp; ref)<span style=\"font-family: Verdana;\"> and the definitions above, <\/span>mutate(one)<span style=\"font-family: Verdana;\"> is valid, while <\/span>mutate(two)<span style=\"font-family: Verdana;\">, <\/span>mutate(three())<span style=\"font-family: Verdana;\">, <\/span>mutate(four())<span style=\"font-family: Verdana;\">, and <\/span>mutate(&#8220;purr&#8221;)<span style=\"font-family: Verdana;\"> are invalid, and all of <\/span>observe(one)<span style=\"font-family: Verdana;\">, <\/span>observe(two)<span style=\"font-family: Verdana;\">, <\/span>observe(three())<span style=\"font-family: Verdana;\">, <\/span>observe(four())<span style=\"font-family: Verdana;\">, and <\/span>observe(&#8220;purr&#8221;)<span style=\"font-family: Verdana;\"> are valid.\u00a0 If you&#8217;re a C++98\/03 programmer, you already knew which of these calls were valid and which were invalid; your &#8220;gut feeling&#8221;, if not your compiler, would have told you that <\/span>mutate(three())<span style=\"font-family: Verdana;\"> was bogus.\u00a0 Your new lvalue\/rvalue vision tells you precisely why (<\/span>three()<span style=\"font-family: Verdana;\"> is an rvalue, and modifiable references can&#8217;t be bound to rvalues).\u00a0 Is that useful?\u00a0 To language lawyers, yes, but not really to normal programmers.\u00a0 After all, you&#8217;ve gotten this far without knowing all of this stuff about lvalues and rvalues.\u00a0 But here&#8217;s the catch: compared to C++98\/03, C++0x has vastly more powerful lvalue\/rvalue vision (in particular, the ability to look at an expression, determine whether it&#8217;s a modifiable\/<\/span>const<span style=\"font-family: Verdana;\"> lvalue\/rvalue, and do something about it).\u00a0 In order to use C++0x effectively, you need lvalue\/rvalue vision too.\u00a0 And now you have it, so we can proceed!<\/span><\/span><\/p>\n<p><span style=\"font-family: Verdana; font-size: medium;\">\u00a0<\/span><\/p>\n<p><span style=\"font-family: Verdana; font-size: medium;\">\u00a0<\/span><\/p>\n<p class=\"MsoNormal\"><b><span style=\"font-family: Verdana; font-size: medium;\">the copying problem<\/span><\/b><\/p>\n<p><span style=\"font-family: Verdana; font-size: medium;\">\u00a0<\/span><\/p>\n<p class=\"MsoNormal\"><span style=\"font-size: medium;\"><span style=\"font-family: Verdana;\">C++98\/03 combines insanely powerful abstraction with insanely efficient execution, but it has a problem: it&#8217;s overly fond of copying.\u00a0 Things with value semantics behave like <\/span>int<span style=\"font-family: Verdana;\">s, so copying a thing doesn&#8217;t modify the source, and the resulting copies are independent.\u00a0 Value semantics are great, except that they tend to lead to unnecessary copies of heavy objects like <\/span>string<span style=\"font-family: Verdana;\">s, <\/span>vector<span style=\"font-family: Verdana;\">s, and so forth.\u00a0 (&#8220;Heavy&#8221; means &#8220;expensive to copy&#8221;; a million-element <\/span>vector<span style=\"font-family: Verdana;\"> is heavy.)\u00a0 The Return Value Optimization (RVO) and Named Return Value Optimization (NRVO), where copy constructors are elided in certain situations, help to alleviate this problem, but they don&#8217;t remove all unnecessary copies.<\/span><\/span><\/p>\n<p><span style=\"font-family: Verdana; font-size: medium;\">\u00a0<\/span><\/p>\n<p class=\"MsoNormal\"><span style=\"font-size: medium;\"><span style=\"font-family: Verdana;\">The <i>most unnecessary<\/i> copies are those where the source is about to be destroyed.\u00a0 Would you photocopy a sheet of paper and then immediately throw away the original, assuming that the original and the photocopy are identical?\u00a0 That would be wasteful; you should keep the original and not bother with the photocopy.\u00a0 Here&#8217;s what I call &#8220;the killer example&#8221;, derived from one of the Standardization Committee&#8217;s examples (in N1377).\u00a0 Suppose that you have a bunch of <\/span>string<span style=\"font-family: Verdana;\">s, like this:<\/span><\/span><\/p>\n<p><span style=\"font-family: Verdana; font-size: medium;\">\u00a0<\/span><\/p>\n<p class=\"MsoNormal\"><span style=\"font-size: medium;\">string s0(&#8220;my mother told me that&#8221;);<\/span><\/p>\n<p>&nbsp;<\/p>\n<p class=\"MsoNormal\"><span style=\"font-size: medium;\">string s1(&#8220;cute&#8221;);<\/span><\/p>\n<p>&nbsp;<\/p>\n<p class=\"MsoNormal\"><span style=\"font-size: medium;\">string s2(&#8220;fluffy&#8221;);<\/span><\/p>\n<p>&nbsp;<\/p>\n<p class=\"MsoNormal\"><span style=\"font-size: medium;\">string s3(&#8220;kittens&#8221;);<\/span><\/p>\n<p>&nbsp;<\/p>\n<p class=\"MsoNormal\"><span style=\"font-size: medium;\">string s4(&#8220;are an essential part of a healthy diet&#8221;);<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-family: Verdana; font-size: medium;\">\u00a0<\/span><\/p>\n<p class=\"MsoNormal\"><span style=\"font-family: Verdana; font-size: medium;\">And that you concatenate them like this:<\/span><\/p>\n<p><span style=\"font-family: Verdana; font-size: medium;\">\u00a0<\/span><\/p>\n<p class=\"Ms oNormal\"><span style=\"font-size: medium;\">string dest = s0 + &#8221; &#8221; + s1 + &#8221; &#8221; + s2 + &#8221; &#8221; + s3 + &#8221; &#8221; + s4;<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-family: Verdana; font-size: medium;\">\u00a0<\/span><\/p>\n<p class=\"MsoNormal\"><span style=\"font-family: Verdana; font-size: medium;\">How efficient is this?\u00a0 (We&#8217;re not worrying about this specific example, which executes in microseconds; we&#8217;re worrying about its generalization, which occurs throughout the entire language.)<\/span><\/p>\n<p><span style=\"font-family: Verdana; font-size: medium;\">\u00a0<\/span><\/p>\n<p class=\"MsoNormal\"><span style=\"font-size: medium;\"><span style=\"font-family: Verdana;\">Each call to <\/span>operator+()<span style=\"font-family: Verdana;\"> returns a temporary <\/span>string<span style=\"font-family: Verdana;\">.\u00a0 There are 8 calls to <\/span>operator+()<span style=\"font-family: Verdana;\"> , so there are 8 temporary <\/span>string<span style=\"font-family: Verdana;\">s.\u00a0 Each one, upon its construction, performs a dynamic memory allocation and copies all of the characters that have been concatenated so far, and later, upon its destruction, performs a dynamic memory deallocation.\u00a0 (If you&#8217;ve heard of the Small String Optimization, which VC performs in order to avoid dynamic memory allocations and deallocations for short <\/span>string<span style=\"font-family: Verdana;\">s, it&#8217;s defeated here by my carefully chosen and sufficiently long <\/span>s0<span style=\"font-family: Verdana;\"> , and even if it applied, it couldn&#8217;t avoid the copying.\u00a0 If you&#8217;ve heard of the Copy-On-Write &#8220;optimization&#8221;, forget about it &#8211; it doesn&#8217;t apply here, and it&#8217;s a pessimization under multithreading, so Standard Library implementations don&#8217;t do it anymore.)<\/span><\/span><\/p>\n<p><span style=\"font-family: Verdana; font-size: medium;\">\u00a0<\/span><\/p>\n<p class=\"MsoNormal\"><span style=\"font-family: Verdana; font-size: medium;\">In fact, because every concatenation copies all of the characters that have been concatenated so far, this has quadratic complexity in the number of concatenations.\u00a0 Yuck!\u00a0 This is extraordinarily wasteful, which is especially embarrassing for C++.\u00a0 Why is this happening, and what can we do about it?<\/span><\/p>\n<p><span style=\"font-family: Verdana; font-size: medium;\">\u00a0<\/span><\/p>\n<p class=\"MsoNormal\"><span style=\"font-size: medium;\"><span style=\"font-family: Verdana;\">The problem is that <\/span>operator+()<span style=\"font-family: Verdana;\"> , which takes two <\/span>const string&amp;<span style=\"font-family: Verdana;\"> or one <\/span>const string&amp;<span style=\"font-family: Verdana;\"> and one <\/span>const char *<span style=\"font-family: Verdana;\"> (there are other overloads, which we aren&#8217;t using here), can&#8217;t tell whether it&#8217;s being fed lvalues versus rvalues, so it always has to create and return a new temporary <\/span>string<span style=\"font-family: Verdana;\"> .\u00a0 Why do lvalues versus rvalues matter?<\/span><\/span><\/p>\n<p><span style=\"font-family: Verdana; font-size: medium;\">\u00a0<\/span><\/p>\n<p class=\"MsoNormal\"><span style=\"font-size: medium;\"><span style=\"font-family: Verdana;\">When evaluating <\/span>s0 + &#8221; &#8220;<span style=\"font-family: Verdana;\"> , it&#8217;s absolutely necessary to create a new temporary <\/span>string<span style=\"font-family: Verdana;\"> .\u00a0 <\/span>s0<span style=\"font-family: Verdana;\"> is an lvalue, naming a persistent object, so we can&#8217;t modify it.\u00a0 (Someone would notice!)\u00a0 But when evaluating <\/span>(s0 + &#8221; &#8220;) + s1<span style=\"font-family: Verdana;\"> , we could simply append <\/span>s1<span style=\"font-family: Verdana;\">&#8216;s contents onto our first temporary <\/span>string<span style=\"font-family: Verdana;\">, instead of creating a second temporary and throwing the first temporary away.\u00a0 This is the <b>key insight behind move semantics<\/b>: because <\/span>s0 + &#8221; &#8220;<span style=\"font-family: Verdana;\"> is an rvalue, an expression referring to a temporary object, no one else in the entire program can observe that temporary object.\u00a0 If we could detect that expression as being a modifiable rvalue, we could then proceed to modify the temporary object arbitrarily, without anyone else noticing.\u00a0 <\/span>operator+()<span style=\"font-family: Verdana;\"> isn&#8217;t &#8220;supposed to&#8221; modify its arguments, but if they&#8217;re modifiable rvalues, who cares?\u00a0 In this manner, each call to <\/span>operator+()<span style=\"font-family: Verdana;\"> can append characters onto a single temporary <\/span>string<span style=\"font-family: Verdana;\"> .\u00a0 This completely eliminates the unnecessary dynamic memory management and unnecessary copying, leaving us with linear complexity.\u00a0 Yay!<\/span><\/span><\/p>\n<p><span style=\"font-family: Verdana; font-size: medium;\">\u00a0<\/span><\/p>\n<p class=\"MsoNormal\"><span style=\"font-size: medium;\"><span style=\"font-family: Verdana;\">Technically speaking, in C++0x, each call to <\/span>operator+()<span style=\"font-family: Verdana;\"> still returns a separate temporary <\/span>string<span style=\"font-family: Verdana;\"> .\u00a0 However, the second temporary <\/span>string<span style=\"font-family: Verdana;\"> (from evaluating <\/span>(s0 + &#8221; &#8220;) + s1<span style=\"font-family: Verdana;\"> ) is constructed by stealing the memory owned by the first temporary <\/span>string<span style=\"font-family: Verdana;\"> (from evaluating <\/span>s0 + &#8221; &#8220;<span style=\"font-family: Verdana;\"> ) and then appending <\/span>s1<span style=\"font-family: Verdana;\">&#8216;s contents onto that memory (which may trigger an ordinary geometric reallocation).\u00a0 &#8220;Stealing&#8221; consists of pointer twiddling: the second temporary copies and then nulls out the first temporary&#8217;s internal pointer.\u00a0 When the first temporary is eventually destroyed (&#8220;at the semicolon&#8221;), its pointer is null, so its destructor does nothing.<\/span><\/span><\/p>\n<p><span style=\"font-family: Verdana; font-size: medium;\">\u00a0<\/span><\/p>\n<p class=\"MsoNormal\"><span style=\"font-family: Verdana; font-size: medium;\">In general, being able to detect modifiable rvalues allows you to engage in &#8220;resource pilfering&#8221;.\u00a0 If the objects referred to by modifiable rvalues own any resources (such as memory), you can steal their resources instead of copying them, since they&#8217;re going to evaporate anyways.\u00a0 Constructing from or assigning from modifiable rvalues by taking what they own is generically referred to as &#8220;moving&#8221;, and moveable objects have &#8220;move semantics&#8221;.<\/span><\/p>\n<p><span style=\"font-family: Verdana; font-size: medium;\">\u00a0<\/span><\/p>\n<p class=\"MsoNormal\"><span style=\"font-size: medium; font-family: Verdana;\">This is extremely useful in many places, such as <\/span><span style=\"font-size: medium;\">vector<\/span><span style=\"font-size: medium; font-family: Verdana;\"> reallocation.\u00a0 When a <\/span><span style=\"font-size: medium;\">vector<\/span><span style=\"font-size: medium; font-family: Verdana;\"> needs more capacity (e.g. during <\/span><span style=\"font-size: medium;\">push_back()<\/span><span style=\"font-size: medium; font-family: Verdana;\">) and undergoes reallocation, it needs to copy elements from the old buffer into the new one. If the objects stored in the vector are expensive to copy (e.g. they could be <span style=\"font-size: medium;\">vectors<\/span>\u00a0<\/span><span style=\"font-family: Verdana; font-size: medium;\">themselves), then this reallocation could be costly. This cost can be greatly reduced in many cases by\u00a0<em>moving<\/em> the old elements into the new buffer rather than copying them. std::vector carries out this operation so long as the move construction of the elements is guaranteed to not throw an exception, as otherwise this could result in lost data.<\/span><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Part 1 of this series covered lambdas, auto, and static_assert. \u00a0 Today, I&#8217;m going to talk about rvalue references, which enable two different things: move semantics and perfect forwarding.\u00a0 This post will be long, because I&#8217;m going to explain how rvalue references work in great detail.\u00a0 They&#8217;re initially very confusing because they distinguish lvalues from [&hellip;]<\/p>\n","protected":false},"author":289,"featured_media":35994,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[],"class_list":["post-4643","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-cplusplus"],"acf":[],"blog_post_summary":"<p>Part 1 of this series covered lambdas, auto, and static_assert. \u00a0 Today, I&#8217;m going to talk about rvalue references, which enable two different things: move semantics and perfect forwarding.\u00a0 This post will be long, because I&#8217;m going to explain how rvalue references work in great detail.\u00a0 They&#8217;re initially very confusing because they distinguish lvalues from [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts\/4643","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/users\/289"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/comments?post=4643"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts\/4643\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/media\/35994"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/media?parent=4643"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/categories?post=4643"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/tags?post=4643"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}