<html>
<head>
<title>Rvalue Reference Recommendations for Chapter 21</title>
<style>
p {text-align:justify}
li {text-align:justify}
blockquote.note
{
    background-color:#E0E0E0;
    padding-left: 15px;
    padding-right: 15px;
    padding-top: 1px;
    padding-bottom: 1px;
}
ins {background-color:#FFFFA0}
del {background-color:#FFFFA0}
</style>
</head>

<body>

<address align=right>
Document number: N1857=05-0117<br>
<br>
<a href="mailto:hinnant@twcny.rr.com">Howard E. Hinnant</a><br>
2005-08-26
</address>
<hr>

<h1 align=center>Rvalue Reference Recommendations for Chapter 21</h1>

<h2>Contents</h2>

<ul>
<li><a href="#Introduction">Introduction</a></li>
<li>
<a href="#21.2 - String classes">21.2 - String classes</a>
</li>
<li>
<a href="#21.3 - Class template basic_string">21.3 - Class template
<tt>basic_string</tt></a>
	<ul>
	<li><a href="#21.3.1 - basic_string constructors">21.3.1 - <tt>basic_string</tt> constructors</a></li>
	<li><a href="#21.3.5.3 - basic_string::assign">21.3.5.3 - <tt>basic_string::assign</tt></a></li>
	<li><a href="#21.3.5.8 - basic_string::swap">21.3.5.8 - <tt>basic_string::swap</tt></a></li>
	<li>
	<a href="#21.3.7 - basic_string non-member functions">21.3.7 -
<tt>basic_string</tt> non-member functions</a>
		<ul>
		<li><a href="#21.3.7.1 - operator+">21.3.7.1 - <tt>operator+</tt></a></li>
		<li><a href="#21.3.7.8 - swap">21.3.7.8 - <tt>swap</tt></a></li>
		<li><a href="#21.3.7.9 - Inserters and extractors">21.3.7.9 - Inserters and extractors</a></li>
		</ul>
	</li>
	</ul>
</li>
</ul>

<h2>Related papers</h2>

<p>
<a href="n1856.html">Rvalue Reference Recommendations for Chapter 20</a><br>
<a href="n1858.html">Rvalue Reference Recommendations for Chapter 23</a><br>
<a href="n1859.html">Rvalue Reference Recommendations for Chapter 24</a><br>
<a href="n1860.html">Rvalue Reference Recommendations for Chapter 25</a><br>
<a href="n1861.html">Rvalue Reference Recommendations for Chapter 26</a><br>
<a href="n1862.html">Rvalue Reference Recommendations for Chapter 27</a>
</p>

<h2><a name="Introduction"></a>Introduction</h2>

<p>
This paper recommends proposed wording with respect to the
<a
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1690.html">rvalue
reference</a> for the
<a
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1804.pdf">C++0X
working draft</a>.
This paper restricts its scope to Chapter 21 "Strings library" for the purpose
of breaking the library work associated with the rvalue reference up into
manageable chunks. This paper largely follows the lead of
<a
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1771.html">N1771:
Impact of the rvalue reference on the Standard Library</a>, but adds more detail
as appropriate.
</p>

<p>
With the exception of this introduction, all non-proposed wording will have a
background color and formatting that
</p>
<blockquote class="note">
looks like this, so that motivation and description is more easily distinguished
from proposed wording.
</blockquote>
<p>
In the proposed wording below, text to be inserted is formatted like
<ins>this</ins>, while wording to be deleted is formatted like <del>this</del>.
</p>

<h2><a name="21.2 - String classes"></a>21.2 - String classes</h2>

<blockquote class="note">
<p>
The recommended changes for chapter 21 have several purposes: </p>

<ul>
<li>Make <tt>basic_string</tt> cheaply move constructible and move assignable.</li>
<li>Allow <tt>swap</tt>ing of <tt>basic_string</tt>s to work with rvalues.</li>
<li>Optimize <tt>operator+</tt>.</li>
<li>Allow I/O with <tt>basic_string</tt>s to work with rvalue streams.</li>
</ul>
</blockquote>

<p>
-3- <b>Header</b> <tt>&lt;string&gt;</tt> <b>synopsis</b>
</p>

<blockquote><pre>
namespace std {
  // <i>21.1, character traits:</i>
  template&lt;class charT&gt;
    struct char_traits;
  template &lt;&gt; struct char_traits&lt;char&gt;;
  template &lt;&gt; struct char_traits&lt;wchar_t&gt;;

  // <i>21.3, basic_string:</i>
  template&lt;class charT, class traits = char_traits&lt;charT&gt;,
           class Allocator = allocator&lt;charT&gt; &gt;
    class basic_string;

  template&lt;class charT, class traits, class Allocator&gt;
    basic_string&lt;charT,traits,Allocator&gt;
      operator+(const basic_string&lt;charT,traits,Allocator&gt;&amp; lhs,
                const basic_string&lt;charT,traits,Allocator&gt;&amp; rhs);
  <ins>template&lt;class charT, class traits, class Allocator&gt;&amp;&amp;
    basic_string&lt;charT,traits,Allocator&gt;
      operator+(basic_string&lt;charT,traits,Allocator&gt;&amp;&amp; lhs,
                const basic_string&lt;charT,traits,Allocator&gt;&amp; rhs);
  template&lt;class charT, class traits, class Allocator&gt;&amp;&amp;
    basic_string&lt;charT,traits,Allocator&gt;
      operator+(const basic_string&lt;charT,traits,Allocator&gt;&amp; lhs,
                basic_string&lt;charT,traits,Allocator&gt;&amp;&amp; rhs);
  template&lt;class charT, class traits, class Allocator&gt;&amp;&amp;
    basic_string&lt;charT,traits,Allocator&gt;
      operator+(basic_string&lt;charT,traits,Allocator&gt;&amp;&amp; lhs,
                basic_string&lt;charT,traits,Allocator&gt;&amp;&amp; rhs);</ins>
  template&lt;class charT, class traits, class Allocator&gt;
    basic_string&lt;charT,traits,Allocator&gt;
      operator+(const charT* lhs,
                const basic_string&lt;charT,traits,Allocator&gt;&amp; rhs);
  <ins>template&lt;class charT, class traits, class Allocator&gt;&amp;&amp;
    basic_string&lt;charT,traits,Allocator&gt;
      operator+(const charT* lhs,
                basic_string&lt;charT,traits,Allocator&gt;&amp;&amp; rhs);</ins>
  template&lt;class charT, class traits, class Allocator&gt;
    basic_string&lt;charT,traits,Allocator&gt;
      operator+(charT lhs, const basic_string&lt;charT,traits,Allocator&gt;&amp; rhs);
  <ins>template&lt;class charT, class traits, class Allocator&gt;&amp;&amp;
    basic_string&lt;charT,traits,Allocator&gt;
      operator+(charT lhs, basic_string&lt;charT,traits,Allocator&gt;&amp;&amp; rhs);</ins>
  template&lt;class charT, class traits, class Allocator&gt;
    basic_string&lt;charT,traits,Allocator&gt;
      operator+(const basic_string&lt;charT,traits,Allocator&gt;&amp; lhs,
                const charT* rhs);
  <ins>template&lt;class charT, class traits, class Allocator&gt;&amp;&amp;
    basic_string&lt;charT,traits,Allocator&gt;
      operator+(basic_string&lt;charT,traits,Allocator&gt;&amp;&amp; lhs,
                const charT* rhs);</ins>
  template&lt;class charT, class traits, class Allocator&gt;
    basic_string&lt;charT,traits,Allocator&gt;
      operator+(const basic_string&lt;charT,traits,Allocator&gt;&amp; lhs, charT rhs);
  <ins>template&lt;class charT, class traits, class Allocator&gt;&amp;&amp;
    basic_string&lt;charT,traits,Allocator&gt;
      operator+(basic_string&lt;charT,traits,Allocator&gt;&amp;&amp; lhs, charT rhs);</ins>

  template&lt;class charT, class traits, class Allocator&gt;
    bool operator==(const basic_string&lt;charT,traits,Allocator&gt;&amp; lhs,
                    const basic_string&lt;charT,traits,Allocator&gt;&amp; rhs);
  template&lt;class charT, class traits, class Allocator&gt;
    bool operator==(const charT* lhs,
                    const basic_string&lt;charT,traits,Allocator&gt;&amp; rhs);
  template&lt;class charT, class traits, class Allocator&gt;
    bool operator==(const basic_string&lt;charT,traits,Allocator&gt;&amp; lhs,
                    const charT* rhs);
  template&lt;class charT, class traits, class Allocator&gt;
    bool operator!=(const basic_string&lt;charT,traits,Allocator&gt;&amp; lhs,
                    const basic_string&lt;charT,traits,Allocator&gt;&amp; rhs);
  template&lt;class charT, class traits, class Allocator&gt;
    bool operator!=(const charT* lhs,
                    const basic_string&lt;charT,traits,Allocator&gt;&amp; rhs);
  template&lt;class charT, class traits, class Allocator&gt;
    bool operator!=(const basic_string&lt;charT,traits,Allocator&gt;&amp; lhs,
                    const charT* rhs);

  template&lt;class charT, class traits, class Allocator&gt;
    bool operator&lt; (const basic_string&lt;charT,traits,Allocator&gt;&amp; lhs,
                    const basic_string&lt;charT,traits,Allocator&gt;&amp; rhs);
  template&lt;class charT, class traits, class Allocator&gt;
    bool operator&lt; (const basic_string&lt;charT,traits,Allocator&gt;&amp; lhs,
                    const charT* rhs);
  template&lt;class charT, class traits, class Allocator&gt;
    bool operator&lt; (const charT* lhs,
                    const basic_string&lt;charT,traits,Allocator&gt;&amp; rhs);
  template&lt;class charT, class traits, class Allocator&gt;
    bool operator&gt; (const basic_string&lt;charT,traits,Allocator&gt;&amp; lhs,
                    const basic_string&lt;charT,traits,Allocator&gt;&amp; rhs);
  template&lt;class charT, class traits, class Allocator&gt;
    bool operator&gt; (const basic_string&lt;charT,traits,Allocator&gt;&amp; lhs,
                    const charT* rhs);
  template&lt;class charT, class traits, class Allocator&gt;
    bool operator&gt; (const charT* lhs,
                    const basic_string&lt;charT,traits,Allocator&gt;&amp; rhs);

  template&lt;class charT, class traits, class Allocator&gt;
    bool operator&lt;=(const basic_string&lt;charT,traits,Allocator&gt;&amp; lhs,
                    const basic_string&lt;charT,traits,Allocator&gt;&amp; rhs);
  template&lt;class charT, class traits, class Allocator&gt;
    bool operator&lt;=(const basic_string&lt;charT,traits,Allocator&gt;&amp; lhs,
                    const charT* rhs);
  template&lt;class charT, class traits, class Allocator&gt;
    bool operator&lt;=(const charT* lhs,
                    const basic_string&lt;charT,traits,Allocator&gt;&amp; rhs);
  template&lt;class charT, class traits, class Allocator&gt;
    bool operator&gt;=(const basic_string&lt;charT,traits,Allocator&gt;&amp; lhs,
                    const basic_string&lt;charT,traits,Allocator&gt;&amp; rhs);
  template&lt;class charT, class traits, class Allocator&gt;
    bool operator&gt;=(const basic_string&lt;charT,traits,Allocator&gt;&amp; lhs,
                    const charT* rhs);
  template&lt;class charT, class traits, class Allocator&gt;
    bool operator&gt;=(const charT* lhs,
                    const basic_string&lt;charT,traits,Allocator&gt;&amp; rhs);

  // <i>21.3.7.8:</i>
  template&lt;class charT, class traits, class Allocator&gt;
     void swap(basic_string&lt;charT,traits,Allocator&gt;&amp; lhs,
               basic_string&lt;charT,traits,Allocator&gt;&amp; rhs);
  <ins>template&lt;class charT, class traits, class Allocator&gt;
     void swap(basic_string&lt;charT,traits,Allocator&gt;&amp;&amp; lhs,
               basic_string&lt;charT,traits,Allocator&gt;&amp; rhs);
  template&lt;class charT, class traits, class Allocator&gt;
     void swap(basic_string&lt;charT,traits,Allocator&gt;&amp; lhs,
               basic_string&lt;charT,traits,Allocator&gt;&amp;&amp; rhs);</ins>

  template&lt;class charT, class traits, class Allocator&gt;
   basic_istream&lt;charT,traits&gt;&amp;
    operator&gt;&gt;(basic_istream&lt;charT,traits&gt;&amp;<ins>&amp;</ins> is,
               basic_string&lt;charT,traits,Allocator&gt;&amp; str);
  template&lt;class charT, class traits, class Allocator&gt;
   basic_ostream&lt;charT, traits&gt;&amp;
    operator&lt;&lt;(basic_ostream&lt;charT, traits&gt;&amp;<ins>&amp;</ins> os,
               const basic_string&lt;charT,traits,Allocator&gt;&amp; str);
  template&lt;class charT, class traits, class Allocator&gt;
   basic_istream&lt;charT,traits&gt;&amp;
     getline(basic_istream&lt;charT,traits&gt;&amp;<ins>&amp;</ins> is,
             basic_string&lt;charT,traits,Allocator&gt;&amp; str,
             charT  delim);
  template&lt;class charT, class traits, class Allocator&gt;
   basic_istream&lt;charT,traits&gt;&amp;
     getline(basic_istream&lt;charT,traits&gt;&amp;<ins>&amp;</ins> is,
             basic_string&lt;charT,traits,Allocator&gt;&amp; str);

  typedef basic_string&lt;char&gt; string;
  typedef basic_string&lt;wchar_t&gt; wstring;
}
</pre></blockquote>

<h2><a name="21.3 - Class template basic_string"></a>21.3 - Class template <tt>basic_string</tt></h2>

<p>-7- ...</p>

<blockquote><pre>
...
class basic_string {
  ...
  basic_string(const basic_string&amp; <i>str</i>);
  <ins>basic_string(basic_string&amp;&amp; <i>str</i>);</ins>
  ...
  basic_string&amp; operator=(const basic_string&amp; <i>str</i>);
  <ins>basic_string&amp; operator=(basic_string&amp;&amp; <i>str</i>);</ins>
  ...
  basic_string&amp; assign(const basic_string&amp; <i>str</i>);
  <ins>basic_string&amp; assign(basic_string&amp;&amp; <i>str</i>);</ins>
  ...
  void swap(basic_string&amp;<ins>&amp;</ins> <i>str</i>);
  ...
};
</pre></blockquote>

<h3><a name="21.3.1 - basic_string constructors"></a>21.3.1 - <tt>basic_string</tt> constructors</h3>

<blockquote class="note">
<p>
<tt>basic_string</tt> needs a move construtor and move assignment operator.
Additionally the member function <tt>assign</tt> which simply takes another
<tt>basic_string</tt> has functionality identical to <tt>operator=</tt> and so
can also behave as the move assignment operator. </p>
</blockquote>

<p>
Insert after paragraph 5:
</p>

<blockquote><pre>
<ins>basic_string(basic_string&amp;&amp; <i>str</i>);</ins>
</pre></blockquote>

<p><ins>
-6- <i>Effects:</i> Constructs an object of class <tt>basic_string</tt> having
the value of the rvalue <tt>basic_string</tt> referred to by <i>str</i>.  The
allocator is move constructed from the allocator contained by <i>str</i>.
<i>str</i> is left in a valid state with an undefined value.
</ins></p>

<p><ins>
-7- <i>Throws:</i> Nothing if the allocator's move constructor does not throw.
</ins></p>

<p>
Insert after paragraph 19:
</p>

<blockquote><pre>
<ins>basic_string&amp;
operator=(basic_string&amp;&amp; <i>str</i>);</ins>
</pre></blockquote>

<p><ins>
-20- <i>Effects:</i> Assigns to this the value of <i>str</i>, leaving <i>str</i>
in a valid but undefined state.  [<i>Note:</i> a valid implementation is
<tt>swap(str)</tt> <i>--end note</i>.]
</ins></p>

<p><ins>
-21- <i>Throws:</i> Nothing.
</ins></p>

<p><ins>
-22- <i>Returns:</i> <tt>*this</tt>.
</ins></p>

<h3><a name="21.3.5.3 - basic_string::assign"></a>21.3.5.3 - <tt>basic_string::assign</tt></h3>

<p>Insert after paragraph 1:</p>

<blockquote><pre>
<ins>basic_string&amp;
assign(basic_string&amp;&amp; <i>str</i>);</ins>
</pre></blockquote>

<p><ins>
-2- <i>Effects:</i> Assigns to this the value of <i>str</i>, leaving <i>str</i>
in a valid but undefined state.  [<i>Note:</i> a valid implementation is
<tt>swap(str)</tt> <i>--end note</i>.]
</ins></p>

<p><ins>
-3- <i>Throws:</i> Nothing.
</ins></p>

<p><ins>
-4- <i>Returns:</i> <tt>*this</tt>.
</ins></p>

<h3><a name="21.3.5.8 - basic_string::swap"></a>21.3.5.8 - <tt>basic_string::swap</tt></h3>

<blockquote class="note">
<p>
Why <tt>swap</tt> needs modification is worthy of some discussion.  The current
shrink-to-fit idiom is: </p>

<blockquote><pre>
string s;
...
string(s).swap(s);
</pre></blockquote>

<p>
Note that this idiom isn't strictly needed for <tt>basic_string</tt> because of
its special <tt>reserve</tt> semantics.  Nonetheless it is a popular idiom. This
paper proposes to also allow the following idioms to accomplish the same thing:
</p>

<blockquote><pre>
s.swap(string(s));
swap(s, string(s));
swap(string(s), s);
</pre></blockquote>

<p>
That is, this paper proposes more flexibility with the syntax of <tt>swap</tt>.
It is perfectly safe and reasonable to <tt>swap</tt> an lvalue with an rvalue.
And that is what is being proposed herein.  It will still not be allowed to
<tt>swap</tt> two rvalues using the namespace scope <tt>swap</tt> function (what
would be the point?). </p>

<blockquote><pre>
swap(string(s), string(s));  // error, no matching function call
</pre></blockquote>

<p>
It will however be allowed to <tt>swap</tt> an rvalue with an rvalue using the
member <tt>swap</tt> function: </p>

<blockquote><pre>
string(s).swap(string(s));  // ok, but useless
</pre></blockquote>

<p>
Even though this is useless, it is allowed in order to enable: </p>

<blockquote><pre>
s.swap(string(s));
</pre></blockquote>

<p>
In order to disable <tt>swap</tt>ing two rvalues with the member <tt>swap</tt>
we would need to adopt
<a
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1784.htm">N1784</a>
which allows overloading on the lvalue-rvalue-ness of the implicit object
parameter. The syntax might look something like: </p>

<blockquote><pre>
...
class basic_string {
  ...
  void swap(basic_string&amp;  <i>str</i>) &amp;;
  void swap(basic_string&amp;&amp; <i>str</i>) &amp;;
  void swap(basic_string&amp;  <i>str</i>) &amp;&amp;;
  ...
};
</pre></blockquote>

<p>
That is, when member <tt>swap</tt> is called with an lvalue
<tt>basic_string</tt>, both lvalue and rvalue <tt>basic_string</tt> arguments
are allowed.  However when member <tt>swap</tt> is called with an rvalue
<tt>basic_string</tt>, only lvalue <tt>basic_string</tt> arguments are allowed.
</p>

<p>
This paper provides no recommendation concerning
<a
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1784.htm">N1784</a>
and merely hopes to clarify how N1784 might affect the standard library.  This
paper currently simply recommends the member function: </p>

<blockquote><pre>
 void swap(basic_string&amp;&amp; <i>s</i>);
</pre></blockquote>

<p>
and the non-member functions: </p>

<blockquote><pre>
template&lt;class charT, class traits, class Allocator&gt;
   void swap(basic_string&lt;charT,traits,Allocator&gt;&amp; lhs,
             basic_string&lt;charT,traits,Allocator&gt;&amp; rhs);
template&lt;class charT, class traits, class Allocator&gt;
   void swap(basic_string&lt;charT,traits,Allocator&gt;&amp;&amp; lhs,
             basic_string&lt;charT,traits,Allocator&gt;&amp; rhs);
template&lt;class charT, class traits, class Allocator&gt;
   void swap(basic_string&lt;charT,traits,Allocator&gt;&amp; lhs,
             basic_string&lt;charT,traits,Allocator&gt;&amp;&amp; rhs);
</pre></blockquote>
</blockquote>

<blockquote><pre>
 void swap(basic_string<del>&lt;charT,traits,Allocator&gt;</del>&amp;<ins>&amp;</ins> <i>s</i>);
</pre></blockquote>

<h3><a name="21.3.7 - basic_string non-member functions"></a>21.3.7 - <tt>basic_string</tt> non-member functions</h3>

<h4><a name="21.3.7.1 - operator+"></a>21.3.7.1 - <tt>operator+</tt></h4>

<blockquote class="note">
<p>
The changes to <tt>operator+</tt> represent an optimization opportunity. </p>

<p>
The basic idea is that if in a string + string operation, if one of the strings
is an rvalue, then it is faster to simply append (or insert) to that rvalue and
return it (by reference), rather than create a new string to hold the
concatenation.  By doing so, expressions involving several <tt>+</tt> operations
effectively only create a single temporary in which the capacity is allowed to
accumulate over the entire expression. </p>

<p>
Because of the (proposed) overloading (pseudo-code): </p>

<blockquote><pre>
string   operator+(const string&amp; , const string&amp; );
string&amp;&amp; operator+(      string&amp;&amp;, const string&amp; );
string&amp;&amp; operator+(const string&amp; ,       string&amp;&amp;);
string&amp;&amp; operator+(      string&amp;&amp;,       string&amp;&amp;);
</pre></blockquote>

<p>
it is guaranteed that if an rvalue argument is given to <tt>operator+</tt>, then
it will bind to a <tt>string&amp;&amp;</tt>.  And if an lvalue (or const rvalue)
argument is given to <tt>operator+</tt>, it will bind to a <tt>const
string&amp;</tt>.  The second overload might be implemented as: </p>

<blockquote><pre>
string&amp;&amp;
operator+(string&amp;&amp; x, const string&amp; y)
{
    return x += y;
}
</pre></blockquote>

<p>
That is, since <tt>x</tt> is an rvalue, it is safe to modify it.  And <tt>x</tt>
may already have sufficient capacity to perform the concatenation, and so a call
to the <tt>string</tt>'s allocator may be avoided.  And finally, <tt>x</tt> may
be returned by rvalue reference (instead of by value) as this will be faster,
even if the return by value is optimized with a move construction of <tt>x</tt>.
</p>

<p>
In contrast, when concatenating two lvalues (the first - and existing -
overload), the function must create a new string to hold the concatenation and
return it by value. </p>

<p>
Consider an expression which performs several string concatenations: </p>

<blockquote><pre>
string s1, s2, s3, s4, s5;
string r = s1 + s2 + s3 + s4 + s5;
</pre></blockquote>

<p>
The first concatenation (of <tt>s1</tt> and <tt>s2</tt>) will use the overload
taking two lvalues, and return a temporary by value.  All other concatenations
will use the second overload, binding the temporary returned from the previous
concatenation to the <i>lhs</i> argument.  And once this temporary is returned
from the first concatenation, it continues to exist throughout the entire chain.
It is passed by reference throughout the expression, accumulating capacity along
the way.  In essence, the above expression executes as if the client had coded:
</p>

<blockquote><pre>
string s1, s2, s3, s4, s5;
string temp = s1 + s2;
temp += s3;
temp += s4;
temp += s5;
string r = move(temp);
</pre></blockquote>

<p>
Contrast the above with the expanded pseudo-code which results from current
(copy semantics) implementations: </p>

<blockquote><pre>
string s1, s2, s3, s4, s5;
string temp1 = s1 + s2;
string temp2 = temp1 + s3;
string temp3 = temp2 + s4;
string r = temp3 + s5;
</pre></blockquote>

<p>
That is, currently a concatenation expression constructs (and destructs) a
number of temporaries that scales linearly with the number of <tt>+</tt>
operations in the expression.  And capacity is not passed from temporary to
temporary.  The proposed (move-optimized) code limits the number of temporaries
to just one, and will accumulate capacity in that single temporary at a
geometric growth rate. </p>

</blockquote>

<blockquote><pre>
template&lt;class charT, class traits, class Allocator&gt;
  basic_string&lt;charT,traits,Allocator&gt;
    operator+(const basic_string&lt;charT,traits,Allocator&gt;&amp; <i>lhs</i>,
              const basic_string&lt;charT,traits,Allocator&gt;&amp; <i>rhs</i>);
</pre></blockquote>

<p>
-1- <i>Returns:</i>
<tt>basic_string&lt;charT,traits,Allocator&gt;(<i>lhs</i>).append(<i>rhs</i>)</tt>.
</p>

<blockquote><pre>
<ins>template&lt;class charT, class traits, class Allocator&gt;&amp;&amp;
  basic_string&lt;charT,traits,Allocator&gt;
    operator+(basic_string&lt;charT,traits,Allocator&gt;&amp;&amp; <i>lhs</i>,
              const basic_string&lt;charT,traits,Allocator&gt;&amp; <i>rhs</i>);</ins>
</pre></blockquote>

<p><ins>
-2- <i>Returns:</i> <tt><i>lhs</i>.append(<i>rhs</i>)</tt>.
</ins></p>

<blockquote><pre>
<ins>template&lt;class charT, class traits, class Allocator&gt;&amp;&amp;
  basic_string&lt;charT,traits,Allocator&gt;
    operator+(const basic_string&lt;charT,traits,Allocator&gt;&amp; <i>lhs</i>,
              basic_string&lt;charT,traits,Allocator&gt;&amp;&amp; <i>rhs</i>);</ins>
</pre></blockquote>

<p><ins>
-3- <i>Returns:</i> <tt><i>rhs</i>.insert(0, <i>lhs</i>)</tt>.
</ins></p>

<blockquote><pre>
<ins>template&lt;class charT, class traits, class Allocator&gt;&amp;&amp;
  basic_string&lt;charT,traits,Allocator&gt;
    operator+(basic_string&lt;charT,traits,Allocator&gt;&amp;&amp; <i>lhs</i>,
              basic_string&lt;charT,traits,Allocator&gt;&amp;&amp; <i>rhs</i>);</ins>
</pre></blockquote>

<p><ins>
-4- <i>Returns:</i> <tt><i>lhs</i>.append(<i>rhs</i>)</tt>. [<i>Note:</i> or
equivalently <tt><i>rhs</i>.insert(0, <i>lhs</i>)</tt> <i>--end note</i>]
</ins></p>

<blockquote><pre>
template&lt;class charT, class traits, class Allocator&gt;
  basic_string&lt;charT,traits,Allocator&gt;
    operator+(const charT* <i>lhs</i>,
              const basic_string&lt;charT,traits,Allocator&gt;&amp; <i>rhs</i>);
</pre></blockquote>

<p>
-5- <i>Returns:</i> <tt>basic_string&lt;charT,traits,Allocator&gt;(<i>lhs</i>) +
<i>rhs</i></tt>.
</p>

<p>
-6- <i>Remarks:</i> Uses <tt>traits::length()</tt>.
</p>

<blockquote><pre><ins>
template&lt;class charT, class traits, class Allocator&gt;
  basic_string&lt;charT,traits,Allocator&gt;&amp;&amp;
    operator+(const charT* <i>lhs</i>,
              basic_string&lt;charT,traits,Allocator&gt;&amp;&amp; <i>rhs</i>);
</ins></pre></blockquote>

<p><ins>
-7- <i>Returns:</i> <tt><i>rhs</i>.insert(0, <i>lhs</i>)</tt>.
</ins></p>

<p><ins>
-8- <i>Remarks:</i> Uses <tt>traits::length()</tt>.
</ins></p>

<blockquote><pre>
template&lt;class charT, class traits, class Allocator&gt;
  basic_string&lt;charT,traits,Allocator&gt;
    operator+(charT <i>lhs</i>,
              const basic_string&lt;charT,traits,Allocator&gt;&amp; <i>rhs</i>);
</pre></blockquote>

<p>
-9- <i>Returns:</i> <tt>basic_string&lt;charT,traits,Allocator&gt;(1,
<i>lhs</i>) + <i>rhs</i></tt>.
</p>

<blockquote><pre><ins>
template&lt;class charT, class traits, class Allocator&gt;
  basic_string&lt;charT,traits,Allocator&gt;&amp;&amp;
    operator+(charT <i>lhs</i>,
              basic_string&lt;charT,traits,Allocator&gt;&amp;&amp; <i>rhs</i>);
</ins></pre></blockquote>

<p><ins>
-10- <i>Returns:</i> <tt><i>rhs</i>.insert(0, 1, <i>lhs</i>)</tt>.
</ins></p>

<blockquote><pre>
template&lt;class charT, class traits, class Allocator&gt;
  basic_string&lt;charT,traits,Allocator&gt;
    operator+(const basic_string&lt;charT,traits,Allocator&gt;&amp; <i>lhs</i>,
              const charT* <i>rhs</i>);
</pre></blockquote>

<p>
-11- <i>Returns:</i> <tt><i>lhs</i> +
basic_string&lt;charT,traits,Allocator&gt;(<i>rhs</i>)</tt>.
</p>

<p>
-12- <i>Remarks:</i> Uses <tt>traits::length()</tt>.
</p>

<blockquote><pre><ins>
template&lt;class charT, class traits, class Allocator&gt;
  basic_string&lt;charT,traits,Allocator&gt;&amp;&amp;
    operator+(basic_string&lt;charT,traits,Allocator&gt;&amp;&amp; <i>lhs</i>,
              const charT* <i>rhs</i>);
</ins></pre></blockquote>

<p><ins>
-13- <i>Returns:</i> <tt><i>lhs</i>.append(<i>rhs</i>)</tt>.
</ins></p>

<p><ins>
-14- <i>Remarks:</i> Uses <tt>traits::length()</tt>.
</ins></p>

<blockquote><pre>
template&lt;class charT, class traits, class Allocator&gt;
  basic_string&lt;charT,traits,Allocator&gt;
    operator+(const basic_string&lt;charT,traits,Allocator&gt;&amp; <i>lhs</i>,
              charT <i>rhs</i>);
</pre></blockquote>

<p>
-15- <i>Returns:</i> <tt><i>lhs</i> +
basic_string&lt;charT,traits,Allocator&gt;(1, <i>rhs</i>)</tt>.
</p>

<blockquote><pre><ins>
template&lt;class charT, class traits, class Allocator&gt;
  basic_string&lt;charT,traits,Allocator&gt;&amp;&amp;
    operator+(basic_string&lt;charT,traits,Allocator&gt;&amp;&amp; <i>lhs</i>,
              charT <i>rhs</i>);
</ins></pre></blockquote>

<p><ins>
-16- <i>Returns:</i> <tt><i>lhs</i>.append(1, <i>rhs</i>)</tt>.
</ins></p>

<h4><a name="21.3.7.8 - swap"></a>21.3.7.8 - <tt>swap</tt></h4>

<blockquote><pre>
template&lt;class charT, class traits, class Allocator&gt;
   void swap(basic_string&lt;charT,traits,Allocator&gt;&amp; lhs,
             basic_string&lt;charT,traits,Allocator&gt;&amp; rhs);
<ins>template&lt;class charT, class traits, class Allocator&gt;
   void swap(basic_string&lt;charT,traits,Allocator&gt;&amp;&amp; lhs,
             basic_string&lt;charT,traits,Allocator&gt;&amp; rhs);
template&lt;class charT, class traits, class Allocator&gt;
   void swap(basic_string&lt;charT,traits,Allocator&gt;&amp; lhs,
             basic_string&lt;charT,traits,Allocator&gt;&amp;&amp; rhs);</ins>
</pre></blockquote>

<p>
-1- <i>Effects:</i> <tt><i>lhs</i>.swap(<i>rhs</i>)</tt>.
</p>

<h4><a name="21.3.7.9 - Inserters and extractors"></a>21.3.7.9 - Inserters and extractors</h4>

<blockquote class="note">
<p>
This section enables <tt>basic_string</tt> I/O to work with rvalue streams as
motivated in
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1690.html#Use%20of%20Rvalue%20Streams">
N1690</a>.  For example clients may want to write a <tt>string</tt> to a
log file, constructing, opening, writing, closing and destructing the
<tt>ofstream</tt> object all with a single statement: </p>

<blockquote><pre>
string s;
...
ofstream("LogFile", ios::app) &lt;&lt; s;
</pre></blockquote>

<p>
<tt>istream</tt>s may also be useful to the client in an rvalue form.  They
could for example be used to parse one <tt>string</tt> into another
<tt>string</tt>: </p>

<blockquote><pre>
string input("one 1");
string word;
int i;
istringstream(input) &gt;&gt; word &gt;&gt; i;  // word == "one", i == 1
</pre></blockquote>

<p>
The use of the <tt>istringstream</tt> in the above example becomes an
implementation detail not worthy of even an identifier.  It is simply a tool
created and discarded to split <tt>input</tt> into <tt>word</tt> and <tt>i</tt>.
</p>

</blockquote>

<blockquote><pre>
template&lt;class charT, class traits, class Allocator&gt;
 basic_istream&lt;charT,traits&gt;&amp;
  operator&gt;&gt;(basic_istream&lt;charT,traits&gt;&amp;<ins>&amp;</ins> is,
             basic_string&lt;charT,traits,Allocator&gt;&amp; str);
</pre></blockquote>

<p>...</p>

<blockquote><pre>
template&lt;class charT, class traits, class Allocator&gt;
 basic_ostream&lt;charT, traits&gt;&amp;
  operator&lt;&lt;(basic_ostream&lt;charT, traits&gt;&amp; os,
             const basic_string&lt;charT,traits,Allocator&gt;&amp; str);

<ins>template&lt;class charT, class traits, class Allocator&gt;
 basic_ostream&lt;charT, traits&gt;&amp;
  operator&lt;&lt;(basic_ostream&lt;charT, traits&gt;&amp;&amp; os,
             const basic_string&lt;charT,traits,Allocator&gt;&amp; str);</ins>
</pre></blockquote>

<p>...</p>

<blockquote><pre>
template&lt;class charT, class traits, class Allocator&gt;
 basic_istream&lt;charT,traits&gt;&amp;
   getline(basic_istream&lt;charT,traits&gt;&amp;<ins>&amp;</ins> is,
           basic_string&lt;charT,traits,Allocator&gt;&amp; str,
           charT  delim);
</pre></blockquote>

<p>...</p>

<blockquote><pre>
template&lt;class charT, class traits, class Allocator&gt;
 basic_istream&lt;charT,traits&gt;&amp;
   getline(basic_istream&lt;charT,traits&gt;&amp;<ins>&amp;</ins> is,
           basic_string&lt;charT,traits,Allocator&gt;&amp; str);
</pre></blockquote>

</body>
</html>
