﻿<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" dir="ltr" lang="en-US">

<head profile="http://gmpg.org/xfn/11">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />

<title>Implicit Move Must Go</title>

<!-- <link rel="stylesheet" href="http://cpp-next.com/wp-content/themes/cpp-next/style.css" type="text/css" media="screen" /> -->
<style type="text/css">
html, body, div, span/* , applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, font, img, ins, kbd, q, s, samp,
small, strike, strong */ /*, sub, sup, tt */ , var,
b, u, i, center,
 ol, ul, li,
fieldset, form, label, legend,
/* table, */ caption /*, tbody, tfoot, thead, tr, th, td */ {
	margin: 0;
	padding: 0;
	border: 0;
	outline: 0;
	font-size: 16px;
	vertical-align: baseline;
	background: transparent;
}

sub, sup {
	margin: 0;
	padding: 0;
	border: 0;
	outline: 0;
	background: transparent;
}

dl, dt, dd {
	padding: 0;
	border: 0;
	outline: 0;
	font-size: 16px;
	vertical-align: baseline;
	background: transparent;
}

table, tbody, tfoot, thead, tr, th, td {
/*	margin: 0;
	padding: 0;
	border: 0;
	outline: 0;
*/	font-size: 14px;
	vertical-align: baseline;
	background: transparent;
}
body {
	line-height: 1;
}
ol, ul {
	list-style: none;
        margin: 0 1em 1em 2em;
	text-align: left;
}

blockquote, q {
	quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
	content: '';
	content: none;
}

/* remember to define focus styles! */
:focus {
	outline: 0;
}

del {
	text-decoration: line-through;
}

/* tables still need 'cellspacing="0"' in the markup */
table {
	border-collapse: collapse;
	border-spacing: 0;
}

.aligncenter,
div.aligncenter {
   display: block;
   margin-left: auto;
   margin-right: auto;
}

.alignleft {
   float: left;
}

.alignright {
   float: right;
}

.wp-caption {
   border: 1px solid #ddd;
   text-align: center;
   background-color: #f3f3f3;
   padding-top: 4px;
   margin: 10px;
   /* optional rounded corners for browsers that support it */
   -moz-border-radius: 3px;
   -khtml-border-radius: 3px;
   -webkit-border-radius: 3px;
   border-radius: 3px;
}

.wp-caption img {
   margin: 0;
   padding: 0;
   border: 0 none;
}

.wp-caption p.wp-caption-text {
   font-size: 11px;
   line-height: 17px;
   padding: 0 4px 5px;
   margin: 0;
}

body {
  background: #fff;
  text-align: center;
  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-weight: normal;
  color: #000 /*#596163*/;
	font-size: 62.5%; /* Resets 1em to 10px */
	overflow-y: scroll; /* so everything doesn't resize when we navigate */
	margin: 0;
	padding: 0;
}

a {
  color: #6d91ba;
  text-decoration: none;
  /*font-size: 14px;*/
}

a:hover {
  color: #9ebbdc; 
  text-decoration: underline;
}

p {
  margin: 0 0 1em 0;
}

span.more_arrow {
  font-size: 70%;
  color: #bdd0e6;
}
.alignright {
  float: right;
}

img.alignright {
  margin: 0 0 .8em .8em;
}

.alignleft {
  float: left;
}

img.alignleft {
  margin: 0 .8em .8em 0;  
}

blockquote {
  display: block;
  margin: 0 0 0 2em;
}

#content li ul li,
#content li ol li {
  margin-left: 2.5em;
}

#content dd {
  margin-left: 2.5em;
}

#page {
  font-size: 1.6em;
  line-height: 20px;
  padding: 0;
  margin: 0;
  visibility: hidden;
}

#header {
  background: #030304 url("i/header.jpg") top left no-repeat;
  width: 100%;
  margin: 0;
  padding: 0 0 1em 0;
}

#navigation {
  background: #ededed;
  min-height: .5em;
  width: 100%;
  margin: 0 0 3em 0;
}

#navigation li {
  color: #999;
  display: block;
  float: left;
  line-height: 1.6em;
  font-size: .7em;
  font-weight: bold;
  padding: .3em 1.4em;
}

#navigation li a {
  color: #666;
}

#navigation li.current_page_item {
  background: #fff;
}

#navigation li.current_page_item a {
  color: #151a1d;
}

#container,
#header_container,
#navigation ul {
  width: 65%;
  text-align: left;
  margin: 0 auto;
  position: relative;
}

#header_container {
  padding: .9em 0 0 0;
}

#content {
  display: block;
  /* width controls percentage of page dedicated to content */
  width: 65%;
  float: left;
}

#content small {
  font-size: 75%;
}

.post ul,
#content ul li,
#content ol ul li {
  list-style-type: square;
}

#content ul > li {
  list-style-type: square !important;
}

#content ol li,
#content ul ol li {
  list-style-type: decimal;
}

ol li {
  list-style-type: decimal;
}

#content ol > li {
  list-style-type: decimal !important;  
}

#sidebar {
  display: block;
  float: left;
  width: 25%;
  margin: 0 0 0 2em;
}

#sidebar ul {
  font-size: 12px;
  line-height: 16px;
}

#sidebar h2 {
  color: #999;
  font-family: Palatino, Georgia, serif;
  font-weight: normal;
  margin: 22px 0 8px 0;
  border-bottom: 1px solid #ddd;
  padding: 0 0 2px 0;
}

#sidebar #subscribe h2 {
  margin-top: 0;
}

#sidebar ul li ul li {
  margin-bottom: 4px;
}

.cat-item {
  color: #aaa;
  font-size: 10px;
}

.cat-item a {
  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-size: 12px;
  padding-right: 3px;
}

#footer {
  color: #aaa;
  clear: left;
  padding: 3em 0;
  font-size: 12px;
}

#footer a {
  color: #aaa;
}

#footer a:hover {
  text-decoration: none;
}

#footer img {
  margin-bottom: -5px;
  margin-left: 2px;
}
/*
h1 a,
h1 {
  color: #bccfcf;
  font-size: 1.2em;
  font-weight: bold;
  text-shadow: 0 0 0 #1c2121;
  margin: 0;
}

h1 a:hover {
  color: #bccfcf;
}

h1 {
  display: block;
}
*/
.description {
  display: block;
  font-family: Georgia, serif;
  font-style: italic;
  color: #565f5f;
  margin: 0.3em 0 0 ;
  font-size: .8em;
  line-height: .9em;
  text-shadow: 0 0 0 #1c2121;
}

.post {
  margin: 0 0 4em 0;
}

.single .post {
  margin: 0 0 2.5em 0;
}

.single_meta {
  display: block;
  margin-top: .4em;
  font-size: 80%;
  color: #999;
}

.post h2 {
  color: #222;
  display: block;
  font-size: 1.7em;
  line-height: 1em;
  letter-spacing: -.03em;
  margin: 0 0 .25em 0;
}

h2.article_view_header {
  margin: 0 0 .4em 0;
}

.post h2 a {
  color: #222;
  font-size: 24px;
}

.post h2 a:hover {
  color: #4f5c5c;
}

.entry {
  font-family: Palatino, Georgia, serif;
  font-size: 1em;
  line-height: 1.5em;
  margin: .1em 0 0 0;
  border-top: .15em solid #eee;
  padding-top: 1.1em;
}

.post_meta_data {
  color: #999;
  display: block;
  font-family: Georgia, serif;
  font-style: italic;
  line-height: 1.8em;
  font-size: .75em;
}

.post_date_category {
  display: block;
  float: left;
  font-size: 13px;
}

.post_meta_data a {
  color: #777;
  font-size: 13px;
}

.comments_info {
  display: block;
  float: right;
  position: relative;
  padding-left: 1.7em;
  padding-right: .4em;
}

.comments_indicator {
  display: block;
  float: left;
  width: 1.3em;
  height: 1.2em;
  background: url("comment.gif"/*tpa=http://cpp-next.com/wp-content/themes/flow/i/comment.gif*/) bottom left no-repeat;
  position: absolute;
  bottom: .3em;
  left: 0;
}

/* Calendar */

#calendar table tr td {
  padding: 1px;
  text-align: center;
}

#calendar caption {
  color:#999999;;
  font-family: Palatino,Georgia,serif;
  margin: 0;
  padding: 0;
  text-indent: 0;
  text-align: left;
}

#calendar #prev, #calendar #next {
  text-align: left;
}

/* Search */

#search {
  display: block;
  position: absolute;
  right: 0;
  top: 1.3em;
  width: 185px;
  height: 24px;
  vertical-align: top;
}

#searchfield_wrapper {
  vertical-align: top;
  background-color: #2f3e46;
  border: none;
  width: 160px;
  height: 24px;
  float: left;
  padding: 0;
  border-top-left-radius: 3px;
  border-bottom-left-radius: 3px;
  -moz-border-radius-bottomleft: 3px;
  -moz-border-radius-topleft: 3px;
  -webkit-border-top-left-radius: 3px;
  -webkit-border-bottom-left-radius: 3px;
  position: relative;
}

#searchfield_wrapper input {
  color: #89a0ac;
  text-shadow: 0 0 0 #27353d;
  background: none;
  border: 0 none;
  font-size: 11px;
  font-weight: normal;
  padding: 5px 0 1px 7px;
}

#searchfield_wrapper #s {
  width: 140px;
}

#searchfield_wrapper #search_submit {
  border: none;
  padding: none;
  float: left;
}

object.comment_icon,
.comment_icon_embed {
  width: 1em;
  height: 1em;
}

/* Comment Display */

#comments {
  border-bottom: .15em solid #eee;
  margin: 0 0 0 0;
}

.comment-body blockquote {
  color: rgb(89, 160, 120);
  margin-bottom: 1em;
}

.commentlist {
  width: 95%;
}
.commentlist .comment, .commentlist .trackback, .commentlist .pingback {
  clear: left;
  display: block;
  border-bottom: .1em solid #eee;
  padding-top: 1em;
}

.commentlist .comment_header {
  display: block;
  margin: 0 0 .7em 0;
}

.commentlist .says {
  display: none;
}

.commentlist .avatar {
  display: block;
  float: left;
  width: 52px;
  height: 52px;
  margin-right: .6em;
}

.commentlist .comment-author {
  font-size: 16px;
  line-height: 14px;
}

.commentlist .comment-meta {
  display: block;
  font-size: 11px;
  line-height: 11px;
  margin-top: 6px;
}

.commentlist .awaiting_approval {
  font-size: 11px;
  line-height: 18px
}

.commentlist cite a.url {
  font-style: normal;
  line-height: 14px;
}

.commentlist .comment-meta a {
  font-family: Georgia, serif;
  font-style: italic;
  color: #999;
}

.comment-full-text {
  clear: left;
  font-size: 90%;
  line-height: 1.4em;
  padding-bottom: 1em;
}

/* Comment Form */

#respond {
  margin-top: .5em;
}

#commentform {
}

#commentform .input_group {
  display: block;
  padding-bottom: .5em;
}

#commentform .input_wrapper,
#commentform .textarea_wrapper {
  background-color: #eaeaea;
  border-radius: 3px;
  -moz-border-radius: 3px;
  -webkit-border-radius: 3px;
  padding: .3em;
  width: 10em;
  float: left;
  margin: 0 .6em 0 0;
} 

#commentform .input_wrapper input,
#commentform .textarea_wrapper textarea {
  color: #111;
  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
  background: none;
  border: 0 none;
  font-weight: normal;
  padding: 0;
  width: 100%;
}

#commentform label {
  font-size: .8em;
}

#commentform .textarea_wrapper {
  width: 26em;
  float: none;
  clear: left;
}

#commentform .input_wrapper input {
  font-size: .75em;
}

#commentform .textarea_wrapper textarea {
  font-size: 80%;
  width: 100%;
}

#commentform .submit_wrapper input {
  clear: left;
  background-color: #6f8989;
  text-shadow: 0 0 0 #6f8989;
  color: #fff;
  border: 1px solid #6f8989;
  padding: .3em 1em;
  border-radius: 3px;
  -moz-border-radius: 3px;
  -webkit-border-radius: 3px;
  font-size: .8em;
  margin-top: .5em;
}

#commentform .submit_wrapper input:hover {
  cursor: pointer;
  background-color: #849d9d;
}

#commentform .submit_wrapper input:active {
  background-color: #141b1b;
}

#commentform #identity_fields {
  width: 17em;
  float: left;
}

/* Facebook Connect */
#fbc_login {
  width: 4em;
  float: left;
  background: url("thin-divider.png"/*tpa=http://cpp-next.com/wp-content/themes/flow/i/thin-divider.png*/) top left no-repeat;
  padding: .4em 0 2em 18px;
  margin-top: .2em;
}

#fbc_login h3 {
  font-size: 85%;
  margin-left: 18px;
}

#fbc_login small, #fbc_login br {
  display: none;
}

#fbc_login:before {
  content: "or...";
  font-size: .8em;
  font-weight: bold;
}

#commentform .fbc_connect_button_area {
  border-left: none;
}

body #fbc_profile {
  display: none !important; /* DO NOT WANT */
}

noscript {
  font-family: Georgia, serif;
  font-size: 24px;
  font-style: italic;
}


/* Archives, Search */

.archive .post, .search .post {
  margin: 0 0 1em 0;
  padding: 0 0 1em 0;
  border-bottom: .15em solid #efefef;
}

.archive h2, .search h2 {
  margin: 0 0 1.5em 0;
}

.archive .post small, .search .post small {
  font-size: .8em;
  line-height: 1.3em;
  font-family: Georgia, serif;
  font-style: italic;
}

.archive .tags, .search .tags, .single .tags {
  color: #aaa;
  font-size: .75em;
  line-height: 1.4em;
}

.archive .tags a, .search .tags a, .single .tags a {
  color: #9eb6d1;
}

.single .single_meta .tags {
  font-size: 100%;
}

.archive .post h3, .search .post h3 {
  font-size: 1.3em;
  line-height: 1.2em;
  margin-bottom: .3em;
}

/* CLEARFIX */

.clearfix:after {
	content: ".";
	display: block;
	clear: both;
	visibility: hidden;
	line-height: 0;
	height: 0;
}
 
.clearfix {
	display: inline-block;
}
 
html[xmlns] .clearfix {
	display: block;
}
 
* html .clearfix {
	height: 1%;
}
</style>
<!--[if IE]>
<style type="text/css">body{overflow-y: auto !important;} 
#searchfield_wrapper input{ padding: 0 !important; position: absolute; top: 5px; left: 6px;}
#search_submit {
  margin-top: -.3em;
}
#page {
  min-width: 640px;
}

#content {
  width: 29.5em;
}</style>
<![endif]-->
<meta name="generator" content="WordPress 3.0.1" />
<!-- <link rel="stylesheet" href="http://cpp-next.com/wp-content/plugins/wp-syntax/wp-syntax.css" type="text/css" media="screen" /> -->
<style type="text/css">
.wp_syntax {
  color: #100;
  background-color: #f9f9f9;
  border: 1px solid silver;
  margin: 0 0 1.5em 0;
  overflow: auto;
}

/* IE FIX */
.wp_syntax {
  overflow-x: auto;
  overflow-y: hidden;
  padding-bottom: expression(this.scrollWidth > this.offsetWidth ? 15 : 0);
  width: 100%;
}

.wp_syntax table {
  border-collapse: collapse;
}

.wp_syntax div, .wp_syntax td {
  vertical-align: top;
  padding: 2px 4px;
}

.wp_syntax .line_numbers {
  text-align: right;
  background-color: #def;
  color: gray;
  overflow: visible;
}

/* potential overrides for other styles */
.wp_syntax pre {
  margin: 0;
  width: auto;
  float: none;
  clear: none;
  overflow: visible;
  font-size: 12px;
  line-height: 1.333;
  white-space: pre;
}

.wp_syntax pre span {
  font-size: 12px;
}</style>
<!-- <link rel="stylesheet" type="text/css" media="screen" href="http://cpp-next.com/wp-content/plugins/mycss/my.css" /> -->
<style type="text/css">
/* typographic tweaks */

dt { 
   font-weight: bold ;
}

div.eop .type-function {
   font-family: sans-serif ;
}

div.eop .concept {
   font-style: italic ;
}

/* Some sidebar bits from docutils */

div.sidebar {
  margin-left: 1em ;
  border: medium outset ;
  padding: 1em ;
  background-color: #ffffee ;
  width: 40% ;
  float: right ;
  clear: right }
 
div.sidebar p.rubric {
  font-family: sans-serif ;
  font-size: medium }
 
p.rubric {
  font-weight: bold ;
  font-size: larger ;
  color: maroon ;
  text-align: center }
 
p.sidebar-title {
  font-family: sans-serif ;
  font-weight: bold ;
  font-size: larger }
 
p.sidebar-subtitle {
  font-family: sans-serif ;
  font-weight: bold }

/* Let's raise footnotes up a bit */
sup { vertical-align:super }

/* Tables in the body need some help */
/* 
	Plain old table styles
	written by Chris Heilmann http://wait-till-i.com
*/
div.entry>table,div.entry>table td,div.entry>table th{
	border:1px solid #000;
	border-collapse:collapse;
	margin:0;
	padding:0;
}
div.entry>table td,div.entry>table th{
	padding:.2em .5em;
	vertical-align:top;
	font-weight:normal;
}
div.entry>table thead th{
	background:#666;
	color:#fff;
}
div.entry>table tbody td{
	background:#ccc;
}
div.entry>table tbody th{
	background:#999;
}
div.entry>table tbody tr.odd td{
	background:#eee;
}
tbody tr.odd th{
	background:#ccc;
}
/* div.entry>table caption{
	text-align:left;
	font-size:140%;
	text-transform:uppercase;
	letter-spacing:-1px;
}*/
div.entry>table table th a:link{
	color:#030;
}
div.entry>table table th a:visited{
	color:#003;
}
div.entry>table table td a:link{
	color:#369;
}
div.entry>table table td a:visited{
	color:#000;
}
div.entry>table table a:hover{
	text-decoration:none;
}
div.entry>table table a:active{
	color:#000;
}

div.admonition, div.attention, div.caution, div.danger, div.error,
div.hint, div.important, div.note, div.tip, div.warning {
  margin: 2em ;
  border: medium outset ;
  padding: 1em }

div.admonition p.admonition-title, div.hint p.admonition-title,
div.important p.admonition-title, div.note p.admonition-title,
div.tip p.admonition-title {
  font-weight: bold ;
  font-family: sans-serif }

div.attention p.admonition-title, div.caution p.admonition-title,
div.danger p.admonition-title, div.error p.admonition-title,
div.warning p.admonition-title {
  color: red ;
  font-weight: bold ;
  font-family: sans-serif }

/* Support for LaTeX logo - see http://edward.oconnor.cx/2007/08/tex-poshlet */
.latex sup {
  font-size: 0.85em;
  vertical-align: 0.15em;
  margin-left: -0.36em;
  margin-right: -0.15em;
}

.tex, .latex, .tex sub, .latex sub {
  font-size: 1em;
}

.tex sub, .latex sub {
  vertical-align: -0.5ex;
  margin-left: -0.1667em;
  margin-right: -0.125em;
}

.tex sub, .latex sub, .latex sup {
  text-transform: uppercase;
}

/* Support for collapsible boxes - see http://www.dynamicdrive.com/dynamicindex17/switchcontent2.htm */

.iconspan{
float: right;
margin: 3px;
cursor:hand;
cursor:pointer;
font-weight: bold;
}


.eg-bar{
background-color: #EEF5D3;
font-weight: bold;
border: 1px solid black;
padding: 3px;
}

div.eg-bar{
width: 500px;
}

.icongroup1{
width: 500px;
}

/* Hackadelic Sliding Notes */

.hackadelic-sliderPanel {
	border: 1px solid #ccc;
	padding: 5px;
	-moz-border-radius: 1em; -webkit-border-radius: 1em;
}

a.hackadelic-sliderButton {
	border: 1px solid lightgrey;
	color: #B3960E;
	padding: 0 3px;
	-moz-border-radius: 1em; -webkit-border-radius: 1em;
}
a.hackadelic-sliderButton:hover {
	border: 1px solid #F0F0E0;
	background-color: #F0F0E0;
}
.entry .hackadelic-sliderPanel {
	background-color: #fcfcfc;
}
.textwidget .hackadelic-sliderButton {
	display: block;
	text-align: center;
	margin: .5em;
}
.textwidget .hackadelic-sliderPanel {
	background-color: #F0F0E0;
}

/* Override for the theme's Javascript requirement */
#page {
  visibility: visible;
}
</style>
<!--Plugin WP Overview (lite) 2010.0913.2010 by sla Active-->


	<style type="text/css">.recentcomments a{display:inline !important;padding:0 !important;margin:0 !important;}</style>

</head>
<body>
<div id="page">


<div id="container">

	
				<div class="post_meta_data clearfix"></div>

		<div class="post-2711 post type-post hentry category-value-semantics tag-committee tag-implicit tag-move tag-rvalue tag-wg21" id="post-2711">
			<h1 class="article_view_header">Implicit Move&nbsp;Must Go</h1>

			<div class="entry">

<p>Document Number: N3153=10-0143<br />Document Date: 2010-10-17<br />
Author: Dave Abrahams &lt;dave@boostpro.com&gt;</p>

<h2>What is Implicit Move?</h2>

<p>In <a href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2009/n2855.html">N2855</a>,
the authors described a surprising effect that occurs when “legacy”
C++03 types are combined in the same object with move-enabled C++0x
types: the combined type could acquire a throwing move constructor.
At that time, we didn&#8217;t have a way to
implement <code>vector::push_back</code> and a few other important
strong-guarantee operations in the presence of a throwing move.</p>

<p>Several independent efforts were made to deal with this problem.  <a href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2009/n2904.pdf">One
approach</a>,
while not a complete solution, shrank the problem space considerably and
had many other benefits: <strong>implicitly generate move constructors and
move assignment operators</strong> when not supplied by the user, in much the
same way that we do for copy constructors and copy assignment operators.
That is the implicit move feature, and it was voted into the working
paper this past spring.</p>

<h2>Further Background</h2>

<p><a href="https://svn.boost.org/svn/boost/sandbox/committee/rvalue_ref/N2983.html">Another
effort</a>,
spurred on by Rani Sharoni&#8217;s <a href="http://cpp-next.com/archive/2009/10/exceptionally-moving/comment-page-1/#comment-203">comments at
C++Next</a>
finally yielded a complete, <a href="https://svn.boost.org/svn/boost/sandbox/committee/rvalue_ref/N2983.html">standalone
solution</a>
to the problem, a form of which was eventually also adopted by the
committee.  Nobody attempted to “repeal” the implicit generation of move
operations from the standard document, not least because of those “many other
benefits” I alluded to earlier.  But now we have a problem that we hadn&#8217;t anticipated.</p>

<h2>The Problem</h2>

<p>Back in August, Scott Meyers
<a href="http://groups.google.com/group/comp.lang.c++/browse_thread/thread/d51d6282f098b3ca">posted</a>
to comp.lang.c++ about a problem where implicit generation of move
constructors could break C++03 class invariants.  For example, the
following valid C++03 program would be broken under the current C++0x
rules (and indeed, is broken in g++4.6 with <code>--std=c++0x</code>) by the
implicit generation of a move constructor:</p>


<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#define _GLIBCXX_DEBUG</span>
<span style="color: #339900;">#include &lt;iostream&gt;</span>
<span style="color: #339900;">#include &lt;vector&gt;</span>
<span style="color: #0000ff;">struct</span> X
<span style="color: #008000;">&#123;</span>
    <span style="color: #666666;">// invariant: v.size() == 5</span>
    X<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span> <span style="color: #008080;">:</span> v<span style="color: #008000;">&#40;</span><span style="color: #0000dd;">5</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span><span style="color: #008000;">&#125;</span>
&nbsp;
    ~X<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
        std<span style="color: #008080;">::</span><span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> v<span style="color: #008000;">&#91;</span><span style="color: #0000dd;">0</span><span style="color: #008000;">&#93;</span> <span style="color: #000080;">&lt;&lt;</span> std<span style="color: #008080;">::</span><span style="color: #007788;">endl</span><span style="color: #008080;">;</span>
    <span style="color: #008000;">&#125;</span>
&nbsp;
 <span style="color: #0000ff;">private</span><span style="color: #008080;">:</span>    
    std<span style="color: #008080;">::</span><span style="color: #007788;">vector</span><span style="color: #000080;">&lt;</span><span style="color: #0000ff;">int</span><span style="color: #000080;">&gt;</span> v<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span>
&nbsp;
<span style="color: #0000ff;">int</span> main<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
    std<span style="color: #008080;">::</span><span style="color: #007788;">vector</span><span style="color: #000080;">&lt;</span>X<span style="color: #000080;">&gt;</span> y<span style="color: #008080;">;</span>
    y.<span style="color: #007788;">push_back</span><span style="color: #008000;">&#40;</span>X<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> <span style="color: #666666;">// X() rvalue: copied in C++03, moved in C++0x</span>
<span style="color: #008000;">&#125;</span></pre></div></div>



<p>The key problem here is that in C++03, <code>X</code> had an invariant that its
<code>v</code> member always had 5 elements.  <code>X::~X()</code> counted on that
invariant, but the newly-introduced move constructor moved from <code>v</code>,
thereby setting its length to zero.</p>

<h2>Tweak #1: Destructors Suppress Implicit Move</h2>

<p>Because rvalues are generally “about to be destroyed,” and the broken
invariant was only detected in <code>X</code>&#8216;s destructor, it&#8217;s tempting to think
that we can &#8220;tweak&#8221; the current rules by preventing the generation of
implicit move constructors when a user-defined destructor is present.
However, the following example would still break (and breaks under
g++4.6 with <code>--std=c++0x</code>):</p>


<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#define _GLIBCXX_DEBUG</span>
<span style="color: #339900;">#include &lt;algorithm&gt;</span>
<span style="color: #339900;">#include &lt;iostream&gt;</span>
<span style="color: #339900;">#include &lt;vector&gt;</span>
&nbsp;
<span style="color: #0000ff;">struct</span> Y
<span style="color: #008000;">&#123;</span>
    <span style="color: #666666;">// invariant: values.size() &gt; 0</span>
    Y<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span> <span style="color: #008080;">:</span> values<span style="color: #008000;">&#40;</span><span style="color: #0000dd;">1</span>, i<span style="color: #000040;">++</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span><span style="color: #008000;">&#125;</span>
    Y<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> n<span style="color: #008000;">&#41;</span> <span style="color: #008080;">:</span> values<span style="color: #008000;">&#40;</span><span style="color: #0000dd;">1</span>,n<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span><span style="color: #008000;">&#125;</span>
&nbsp;
    <span style="color: #0000ff;">bool</span> operator<span style="color: #000080;">==</span><span style="color: #008000;">&#40;</span>Y <span style="color: #0000ff;">const</span><span style="color: #000040;">&amp;</span> rhs<span style="color: #008000;">&#41;</span> <span style="color: #0000ff;">const</span>
    <span style="color: #008000;">&#123;</span> 
        <span style="color: #0000ff;">return</span> this<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>values <span style="color: #000080;">==</span> rhs.<span style="color: #007788;">values</span><span style="color: #008080;">;</span>
    <span style="color: #008000;">&#125;</span>
&nbsp;
    <span style="color: #0000ff;">int</span> operator<span style="color: #008000;">&#91;</span><span style="color: #008000;">&#93;</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">unsigned</span> i<span style="color: #008000;">&#41;</span> <span style="color: #0000ff;">const</span>
    <span style="color: #008000;">&#123;</span> <span style="color: #0000ff;">return</span> values<span style="color: #008000;">&#91;</span>i<span style="color: #008000;">&#93;</span><span style="color: #008080;">;</span> <span style="color: #008000;">&#125;</span>
&nbsp;
 <span style="color: #0000ff;">private</span><span style="color: #008080;">:</span>
    <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">int</span> i<span style="color: #008080;">;</span>
    std<span style="color: #008080;">::</span><span style="color: #007788;">vector</span><span style="color: #000080;">&lt;</span><span style="color: #0000ff;">int</span><span style="color: #000080;">&gt;</span> values<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span>
&nbsp;
<span style="color: #0000ff;">int</span> Y<span style="color: #008080;">::</span><span style="color: #007788;">i</span> <span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
&nbsp;
<span style="color: #0000ff;">int</span> main<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>   
    Y ys<span style="color: #008000;">&#91;</span><span style="color: #0000dd;">10</span><span style="color: #008000;">&#93;</span><span style="color: #008080;">;</span>
    std<span style="color: #008080;">::</span><span style="color: #0000dd;">remove</span><span style="color: #008000;">&#40;</span><span style="color: #000040;">&amp;</span>ys<span style="color: #008000;">&#91;</span><span style="color: #0000dd;">0</span><span style="color: #008000;">&#93;</span>, <span style="color: #000040;">&amp;</span>ys<span style="color: #008000;">&#91;</span><span style="color: #0000dd;">0</span><span style="color: #008000;">&#93;</span><span style="color: #000040;">+</span><span style="color: #0000dd;">10</span>, Y<span style="color: #008000;">&#40;</span><span style="color: #0000dd;">5</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    std<span style="color: #008080;">::</span><span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> ys<span style="color: #008000;">&#91;</span><span style="color: #0000dd;">9</span><span style="color: #008000;">&#93;</span><span style="color: #008000;">&#91;</span><span style="color: #0000dd;">0</span><span style="color: #008000;">&#93;</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span></pre></div></div>



<p>In C++03, there&#8217;s no way to create a <code>Y</code> with a zero-length <code>values</code>
member, but because <code>std::remove</code> is allowed to use move operations in
C++0x, it can leave a moved-from <code>Y</code> at the end of the array, and that
could be empty, causing undefined behavior in the last line.</p>

<div class="note">

<p class="admonition-title">About the use of <code>std::remove</code> in these examples</p>

<p>In C++03, <code>std::remove</code> eliminates values from a range
by <em>assigning over them</em> (technically it can also use swap, but
let's assume assignment for now).  Since it can&#8217;t actually
change sequence <em>structure</em>, it assigns over the unwanted
elements with values from later in the sequence, pushing everything
toward the front until there&#8217;s a subrange containing only
what&#8217;s desired, and returns the new end iterator of that
subrange .  For example, after <code>remove</code>ing <code>0</code>
from the sequence <code>0 1 2 0 5</code>, we&#8217;d end up
with <code>1 2 5</code>, and then <code>0 5</code>—the last two
elements of the sequence would be unchanged.</p>

<p>In C++0x, we have move semantics, and <code>std::remove</code> has
permission to use <em>move assignment</em>.  So in C++0x, we&#8217;d
end up with <code>1 2 5 0 x</code> at the end of the sequence,
where <code>x</code> is the value left over after moving from the last
element—if the elements are <code>int</code>s, that would
be <code>5</code>, but if they are <code>BigNum</code>s, it could be
anything.  Similar properties are shared
by <code>std::remove_if</code> and <code>std::unique</code>.</p>

<p>There&#8217;s another way moved-from values can be exposed to C++03 code
running under C++0x: an algorithm such as <code>sort</code> can throw an exception
while shuffling elements, and you can then observe a state where not
everything has been moved back into place.  Showing that just makes for
more complicated examples, however.</p>

</div>

<h2>Tweak #2: Constructors Suppress Implicit Move</h2>

<p>It&#8217;s also tempting to think that at least in classes without a
user-defined constructor, we could safely conclude that there&#8217;s no
intention to maintain an invariant, but that reasoning, too, is
flawed:</p>


<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#define _GLIBCXX_DEBUG</span>
<span style="color: #339900;">#include &lt;iostream&gt;</span>
<span style="color: #339900;">#include &lt;vector&gt;</span>
&nbsp;
<span style="color: #666666;">// An always-initialized wrapper for unsigned int</span>
<span style="color: #0000ff;">struct</span> Number
<span style="color: #008000;">&#123;</span>
    Number<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">unsigned</span> x <span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008000;">&#41;</span> <span style="color: #008080;">:</span> value<span style="color: #008000;">&#40;</span>x<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span><span style="color: #008000;">&#125;</span>
    operator <span style="color: #0000ff;">unsigned</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span> <span style="color: #0000ff;">const</span> <span style="color: #008000;">&#123;</span> <span style="color: #0000ff;">return</span> value<span style="color: #008080;">;</span> <span style="color: #008000;">&#125;</span>
 <span style="color: #0000ff;">private</span><span style="color: #008080;">:</span>
    <span style="color: #0000ff;">unsigned</span> value<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span>
&nbsp;
<span style="color: #0000ff;">struct</span> Y
<span style="color: #008000;">&#123;</span>
    <span style="color: #666666;">// Invariant: length == values.size().  Default ctor is fine.</span>
&nbsp;
    <span style="color: #666666;">// Maintains the invariant</span>
    <span style="color: #0000ff;">void</span> resize<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">unsigned</span> n<span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
        std<span style="color: #008080;">::</span><span style="color: #007788;">vector</span><span style="color: #000080;">&lt;</span><span style="color: #0000ff;">int</span><span style="color: #000080;">&gt;</span> s<span style="color: #008000;">&#40;</span>n<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
        swap<span style="color: #008000;">&#40;</span>s,values<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
        length <span style="color: #000080;">=</span> Number<span style="color: #008000;">&#40;</span>n<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #008000;">&#125;</span>
&nbsp;
    <span style="color: #0000ff;">bool</span> operator<span style="color: #000080;">==</span><span style="color: #008000;">&#40;</span>Y <span style="color: #0000ff;">const</span><span style="color: #000040;">&amp;</span> rhs<span style="color: #008000;">&#41;</span> <span style="color: #0000ff;">const</span>
    <span style="color: #008000;">&#123;</span> 
        <span style="color: #0000ff;">return</span> this<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>values <span style="color: #000080;">==</span> rhs.<span style="color: #007788;">values</span><span style="color: #008080;">;</span>
    <span style="color: #008000;">&#125;</span>
&nbsp;
    <span style="color: #0000ff;">friend</span> std<span style="color: #008080;">::</span><span style="color: #007788;">ostream</span><span style="color: #000040;">&amp;</span> operator<span style="color: #000080;">&lt;&lt;</span><span style="color: #008000;">&#40;</span>std<span style="color: #008080;">::</span><span style="color: #007788;">ostream</span><span style="color: #000040;">&amp;</span> s, Y <span style="color: #0000ff;">const</span><span style="color: #000040;">&amp;</span> a<span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
        <span style="color: #0000ff;">for</span> <span style="color: #008000;">&#40;</span><span style="color: #0000ff;">unsigned</span> i <span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span> i <span style="color: #000080;">&lt;</span> a.<span style="color: #007788;">length</span><span style="color: #008080;">;</span> <span style="color: #000040;">++</span>i<span style="color: #008000;">&#41;</span>
            std<span style="color: #008080;">::</span><span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> a.<span style="color: #007788;">values</span><span style="color: #008000;">&#91;</span>i<span style="color: #008000;">&#93;</span> <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot; &quot;</span><span style="color: #008080;">;</span>
        <span style="color: #0000ff;">return</span> s<span style="color: #008080;">;</span>
    <span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span>
&nbsp;
 <span style="color: #0000ff;">private</span><span style="color: #008080;">:</span>
    std<span style="color: #008080;">::</span><span style="color: #007788;">vector</span><span style="color: #000080;">&lt;</span><span style="color: #0000ff;">int</span><span style="color: #000080;">&gt;</span> values<span style="color: #008080;">;</span>
    Number length<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span>
&nbsp;
<span style="color: #0000ff;">int</span> main<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>   
    std<span style="color: #008080;">::</span><span style="color: #007788;">vector</span><span style="color: #000080;">&lt;</span>Y<span style="color: #000080;">&gt;</span> z<span style="color: #008000;">&#40;</span><span style="color: #0000dd;">1</span>, Y<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
    Y a<span style="color: #008080;">;</span>
    a.<span style="color: #007788;">resize</span><span style="color: #008000;">&#40;</span><span style="color: #0000dd;">2</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    z.<span style="color: #007788;">push_back</span><span style="color: #008000;">&#40;</span>a<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
    std<span style="color: #008080;">::</span><span style="color: #0000dd;">remove</span><span style="color: #008000;">&#40;</span>z.<span style="color: #007788;">begin</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, z.<span style="color: #007788;">end</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, Y<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    std<span style="color: #008080;">::</span><span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> z<span style="color: #008000;">&#91;</span><span style="color: #0000dd;">1</span><span style="color: #008000;">&#93;</span> <span style="color: #000080;">&lt;&lt;</span> std<span style="color: #008080;">::</span><span style="color: #007788;">endl</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span></pre></div></div>



<p>In this case, the invariant that <code>length == values.size()</code> was
established by the well-understood default-construction behavior of
subobjects, but implicit move generation has violated it.</p>

<h2>Tweak #3: Private Members Suppress Implicit Move</h2>

<p>It&#8217;s also tempting to think that we can use private members to
indicate that an invariant needs to be preserved; that a “C-style
<code>struct</code>” is not encapsulated and has no need of protection.  But the
members of a privately-inherited struct are effectively encapsulated
and private with respect to the derived class.  It is not uncommon to
see members moved into an implementation detail struct, which is then
used as a base class:</p>


<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #666666;">// Modified fragment of previous example.  Replace the definition</span>
<span style="color: #666666;">// of Y with this code.</span>
&nbsp;
<span style="color: #0000ff;">namespace</span> detail
<span style="color: #008000;">&#123;</span>
  <span style="color: #0000ff;">struct</span> Y_impl
  <span style="color: #008000;">&#123;</span>
      std<span style="color: #008080;">::</span><span style="color: #007788;">vector</span><span style="color: #000080;">&lt;</span><span style="color: #0000ff;">int</span><span style="color: #000080;">&gt;</span> values<span style="color: #008080;">;</span>
      Number length<span style="color: #008080;">;</span>
  <span style="color: #008000;">&#125;</span>
<span style="color: #008000;">&#125;</span>
&nbsp;
<span style="color: #0000ff;">struct</span> Y <span style="color: #008080;">:</span> <span style="color: #0000ff;">private</span> Y_impl
<span style="color: #008000;">&#123;</span>
    <span style="color: #0000ff;">void</span> resize<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">unsigned</span> n<span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
        std<span style="color: #008080;">::</span><span style="color: #007788;">vector</span><span style="color: #000080;">&lt;</span><span style="color: #0000ff;">int</span><span style="color: #000080;">&gt;</span> s<span style="color: #008000;">&#40;</span>n<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
        swap<span style="color: #008000;">&#40;</span>s,values<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
        length <span style="color: #000080;">=</span> Number<span style="color: #008000;">&#40;</span>n<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #008000;">&#125;</span>
&nbsp;
    <span style="color: #0000ff;">bool</span> operator<span style="color: #000080;">==</span><span style="color: #008000;">&#40;</span>Y <span style="color: #0000ff;">const</span><span style="color: #000040;">&amp;</span> rhs<span style="color: #008000;">&#41;</span> <span style="color: #0000ff;">const</span>
    <span style="color: #008000;">&#123;</span> 
        <span style="color: #0000ff;">return</span> this<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>values <span style="color: #000080;">==</span> rhs.<span style="color: #007788;">values</span><span style="color: #008080;">;</span>
    <span style="color: #008000;">&#125;</span>
&nbsp;
    <span style="color: #0000ff;">friend</span> std<span style="color: #008080;">::</span><span style="color: #007788;">ostream</span><span style="color: #000040;">&amp;</span> operator<span style="color: #000080;">&lt;&lt;</span><span style="color: #008000;">&#40;</span>std<span style="color: #008080;">::</span><span style="color: #007788;">ostream</span><span style="color: #000040;">&amp;</span> s, Y <span style="color: #0000ff;">const</span><span style="color: #000040;">&amp;</span> a<span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
        <span style="color: #0000ff;">for</span> <span style="color: #008000;">&#40;</span><span style="color: #0000ff;">unsigned</span> i <span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span> i <span style="color: #000080;">&lt;</span> a.<span style="color: #007788;">length</span><span style="color: #008080;">;</span> <span style="color: #000040;">++</span>i<span style="color: #008000;">&#41;</span>
            std<span style="color: #008080;">::</span><span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> a.<span style="color: #007788;">values</span><span style="color: #008000;">&#91;</span>i<span style="color: #008000;">&#93;</span> <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot; &quot;</span><span style="color: #008080;">;</span>
        <span style="color: #0000ff;">return</span> s<span style="color: #008080;">;</span>
    <span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span></pre></div></div>



<h2>Real-World Examples</h2>

<p>Of course these examples are all somewhat contrived, but they are not
unrealistic.  We&#8217;ve already found classes in the (new) standard
library—<code>std::piecewise_linear_distribution::param_type</code> and
<code>std::piecewise_linear_distribution</code>—that have been implemented in
exactly such a way as to expose the same problems.  In particular,
they were shipped with g++4.5, which had no explicit move, and not
updated for g++4.6, which did.  Thus they were broken by the
introduction of implicitly-generated move constructors.</p>

<h2>Summary</h2>

<p>I actually like implicit move.  It would be a very good idea in a new
language, where we didn&#8217;t have legacy code to consider.
Unfortunately, it breaks fairly pedestrian-looking C++03 examples.  We
could continue to explore tweaks to the rules for implicit move
generation, but each tweak we need to make eliminates implicit move
for another category of types where it could have been useful, and
weakens confidence that we have analyzed the situation correctly.  And
it&#8217;s very late in the standardization process to tolerate such
uncertainty.</p>

<h2>Conclusions</h2>

<p>It is time to remove implicitly-generated move operations from the
draft.  That suggestion may seem radical, but implicit move was
<a href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2009/n2904.pdf">proposed</a>
very late in the process on the premise that it “treated&#8230;the root
cause” of the exception-safety issues revealed in
<a href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2009/n2855.html">N2855</a>.
However, it did not treat those causes: we still <a href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2010/n3050.html">needed
<code>noexcept</code></a>. Therefore, implicitly-generated move operations can be
removed without fundamentally undermining the usefulness or safety of
rvalue references.</p>

<p>The default semantics of the proposed implicit move operations are
still quite useful and commonly-needed.  Therefore, while removing
implicit generation, we should retain the ability to produce those
semantics with “<code>= default</code>.”  It would also be nice if the rules
allowed a more concise way to say “give me all the defaults for move
and copy assignment,” but this paper offers no such proposal.</p>
								

			</div>
		</div>

	
	</div>
</div></div>



</div>
</div>


</body>
</html>
