<!doctype html><html lang="en">
 <head>
  <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
  <meta content="width=device-width, initial-scale=1, shrink-to-fit=no" name="viewport">
  <title>P2952R2: auto&amp; operator=(X&amp;&amp;) = default</title>
<style data-fill-with="stylesheet">/******************************************************************************
 *                   Style sheet for the W3C specifications                   *
 *
 * Special classes handled by this style sheet include:
 *
 * Indices
 *   - .toc for the Table of Contents (<ol class="toc">)
 *     + <span class="secno"> for the section numbers
 *   - #toc for the Table of Contents (<nav id="toc">)
 *   - ul.index for Indices (<a href="#ref">term</a><span>, in § N.M</span>)
 *   - table.index for Index Tables (e.g. for properties or elements)
 *
 * Structural Markup
 *   - table.data for general data tables
 *     -> use 'scope' attribute, <colgroup>, <thead>, and <tbody> for best results !
 *     -> use <table class='complex data'> for extra-complex tables
 *     -> use <td class='long'> for paragraph-length cell content
 *     -> use <td class='pre'> when manual line breaks/indentation would help readability
 *   - dl.switch for switch statements
 *   - ol.algorithm for algorithms (helps to visualize nesting)
 *   - .figure and .caption (HTML4) and figure and figcaption (HTML5)
 *     -> .sidefigure for right-floated figures
 *   - ins/del
 *     -> ins/del.c### for candidate and proposed changes (amendments)
 *
 * Code
 *   - pre and code
 *
 * Special Sections
 *   - .note       for informative notes             (div, p, span, aside, details)
 *   - .example    for informative examples          (div, p, pre, span)
 *   - .issue      for issues                        (div, p, span)
 *   - .advisement for loud normative statements     (div, p, strong)
 *   - .annoying-warning for spec obsoletion notices (div, aside, details)
 *   - .correction for "candidate corrections"       (div, aside, details, section)
 *   - .addition   for "candidate additions"         (div, aside, details, section)
 *   - .correction.proposed for "proposed corrections" (div, aside, details, section)
 *   - .addition.proposed   for "proposed additions"   (div, aside, details, section)
 *
 * Definition Boxes
 *   - pre.def   for WebIDL definitions
 *   - table.def for tables that define other entities (e.g. CSS properties)
 *   - dl.def    for definition lists that define other entitles (e.g. HTML elements)
 *
 * Numbering
 *   - .secno for section numbers in .toc and headings (<span class='secno'>3.2</span>)
 *   - .marker for source-inserted example/figure/issue numbers (<span class='marker'>Issue 4</span>)
 *   - ::before styled for CSS-generated issue/example/figure numbers:
 *     -> Documents wishing to use this only need to add
 *        figcaption::before,
 *        .caption::before { content: "Figure "  counter(figure) " ";  }
 *        .example::before { content: "Example " counter(example) " "; }
 *        .issue::before   { content: "Issue "   counter(issue) " ";   }
 *
 * Header Stuff (ignore, just don't conflict with these classes)
 *   - .head for the header
 *   - .copyright for the copyright
 *
 * Outdated warning for old specs
 *
 * Miscellaneous
 *   - .overlarge for things that should be as wide as possible, even if
 *     that overflows the body text area. This can be used on an item or
 *     on its container, depending on the effect desired.
 *     Note that this styling basically doesn't help at all when printing,
 *     since A4 paper isn't much wider than the max-width here.
 *     It's better to design things to fit into a narrower measure if possible.
 *
 *   - js-added ToC jump links (see fixup.js)
 *
 ******************************************************************************/

/* color variables included separately for reliability */

/******************************************************************************/
/*                                    Body                                    */
/******************************************************************************/

	html {
	}

	body {
		counter-reset: example figure issue;

		/* Layout */
		max-width: 50em;			  /* limit line length to 50em for readability   */
		margin: 0 auto;				/* center text within page                    */
		padding: 1.6em 1.5em 2em 50px; /* assume 16px font size for downlevel clients */
		padding: 1.6em 1.5em 2em calc(26px + 1.5em); /* leave space for status flag    */

		/* Typography */
		line-height: 1.5;
		font-family: sans-serif;
		widows: 2;
		orphans: 2;
		word-wrap: break-word;
		overflow-wrap: break-word;
		hyphens: auto;

		color: black;
		color: var(--text);
		background: white top left fixed no-repeat;
		background: var(--bg) top left fixed no-repeat;
		background-size: 25px auto;
	}


/******************************************************************************/
/*                         Front Matter & Navigation                          */
/******************************************************************************/

/** Header ********************************************************************/

	div.head { margin-bottom: 1em; }
	div.head hr { border-style: solid; }

	div.head h1 {
		font-weight: bold;
		margin: 0 0 .1em;
		font-size: 220%;
	}

	div.head h2 { margin-bottom: 1.5em;}

/** W3C Logo ******************************************************************/

	.head .logo {
		float: right;
		margin: 0.4rem 0 0.2rem .4rem;
	}

	.head img[src*="logos/W3C"] {
		display: block;
		border: solid #1a5e9a;
		border: solid var(--logo-bg);
		border-width: .65rem .7rem .6rem;
		border-radius: .4rem;
		background: #1a5e9a;
		background: var(--logo-bg);
		color: white;
		color: var(--logo-text);
		font-weight: bold;
	}

	.head a:hover > img[src*="logos/W3C"],
	.head a:focus > img[src*="logos/W3C"] {
		opacity: .8;
	}

	.head a:active > img[src*="logos/W3C"] {
		background: #c00;
		background: var(--logo-active-bg);
		border-color: #c00;
		border-color: var(--logo-active-bg);
	}

	/* see also additional rules in Link Styling section */

/** Copyright *****************************************************************/

	p.copyright,
	p.copyright small { font-size: small; }

/** Back to Top / ToC Toggle **************************************************/

	@media print {
		#toc-nav {
			display: none;
		}
	}
	@media not print {
		#toc-nav {
			position: fixed;
			z-index: 3;
			bottom: 0; left: 0;
			margin: 0;
			min-width: 1.33em;
			border-top-right-radius: 2rem;
			box-shadow: 0 0 2px;
			font-size: 1.5em;
		}
		#toc-nav > a {
			display: block;
			white-space: nowrap;

			height: 1.33em;
			padding: .1em 0.3em;
			margin: 0;

			box-shadow: 0 0 2px;
			border: none;
			border-top-right-radius: 1.33em;

			color: #707070;
			color: var(--tocnav-normal-text);
			background: white;
			background: var(--tocnav-normal-bg);
		}
		#toc-nav > a:hover,
		#toc-nav > a:focus {
			color: black;
			color: var(--tocnav-hover-text);
			background: #f8f8f8;
			background: var(--tocnav-hover-bg);
		}
		#toc-nav > a:active {
			color: #c00;
			color: var(--tocnav-active-text);
			background: white;
			background: var(--tocnav-active-bg);
		}

		#toc-nav > #toc-jump {
			padding-bottom: 2em;
			margin-bottom: -1.9em;
		}

		/* statusbar gets in the way on keyboard focus; remove once browsers fix */
		#toc-nav > a[href="#toc"]:not(:hover):focus:last-child {
			padding-bottom: 1.5rem;
		}

		#toc-nav:not(:hover) > a:not(:focus) > span + span {
			/* Ideally this uses :focus-within on #toc-nav */
			display: none;
		}
		#toc-nav > a > span + span {
			padding-right: 0.2em;
		}
	}

/** ToC Sidebar ***************************************************************/

	/* Floating sidebar */
	@media screen {
		body.toc-sidebar #toc {
			position: fixed;
			top: 0; bottom: 0;
			left: 0;
			width: 23.5em;
			max-width: 80%;
			max-width: calc(100% - 2em - 26px);
			overflow: auto;
			padding: 0 1em;
			padding-left: 42px;
			padding-left: calc(1em + 26px);
			color: black;
			color: var(--tocsidebar-text);
			background: inherit;
			background-color: #f7f8f9;
			background-color: var(--tocsidebar-bg);
			z-index: 1;
			box-shadow: -.1em 0 .25em rgba(0,0,0,.1) inset;
			box-shadow: -.1em 0 .25em var(--tocsidebar-shadow) inset;
		}
		body.toc-sidebar #toc h2 {
			margin-top: .8rem;
			font-variant: small-caps;
			font-variant: all-small-caps;
			text-transform: lowercase;
			font-weight: bold;
			color: gray;
			color: hsla(203,20%,40%,.7);
			color: var(--tocsidebar-heading-text);
		}
		body.toc-sidebar #toc-jump:not(:focus) {
			width: 0;
			height: 0;
			padding: 0;
			position: absolute;
			overflow: hidden;
		}
	}
	/* Hide main scroller when only the ToC is visible anyway */
	@media screen and (max-width: 28em) {
		body.toc-sidebar {
			overflow: hidden;
		}
	}

	/* Sidebar with its own space */
	@media screen and (min-width: 78em) {
		body:not(.toc-inline) #toc {
			position: fixed;
			top: 0; bottom: 0;
			left: 0;
			width: 23.5em;
			overflow: auto;
			padding: 0 1em;
			padding-left: 42px;
			padding-left: calc(1em + 26px);
			color: black;
			color: var(--tocsidebar-text);
			background: inherit;
			background-color: #f7f8f9;
			background-color: var(--tocsidebar-bg);
			z-index: 1;
			box-shadow: -.1em 0 .25em rgba(0,0,0,.1) inset;
			box-shadow: -.1em 0 .25em var(--tocsidebar-shadow) inset;
		}
		body:not(.toc-inline) #toc h2 {
			margin-top: .8rem;
			font-variant: small-caps;
			font-variant: all-small-caps;
			text-transform: lowercase;
			font-weight: bold;
			color: gray;
			color: hsla(203,20%,40%,.7);
			color: var(--tocsidebar-heading-text);
		}

		body:not(.toc-inline) {
			padding-left: 29em;
		}
		/* See also Overflow section at the bottom */

		body:not(.toc-inline) #toc-jump:not(:focus) {
			width: 0;
			height: 0;
			padding: 0;
			position: absolute;
			overflow: hidden;
		}
	}
	@media screen and (min-width: 90em) {
		body:not(.toc-inline) {
			margin: 0 4em;
		}
	}

/******************************************************************************/
/*                                Sectioning                                  */
/******************************************************************************/

/** Headings ******************************************************************/

	h1, h2, h3, h4, h5, h6, dt {
		page-break-after: avoid;
		page-break-inside: avoid;
		font: 100% sans-serif;   /* Reset all font styling to clear out UA styles */
		font-family: inherit;	/* Inherit the font family. */
		line-height: 1.2;		/* Keep wrapped headings compact */
		hyphens: manual;		/* Hyphenated headings look weird */
	}

	h2, h3, h4, h5, h6 {
		margin-top: 3rem;
	}

	h1, h2, h3 {
		color: #005A9C;
		color: var(--heading-text);
	}

	h1 { font-size: 170%; }
	h2 { font-size: 140%; }
	h3 { font-size: 120%; }
	h4 { font-weight: bold; }
	h5 { font-style: italic; }
	h6 { font-variant: small-caps; }
	dt { font-weight: bold; }

/** Subheadings ***************************************************************/

	h1 + h2,
	#profile-and-date {
		/* #profile-and-date is a subtitle in an H2 under the H1 */
		margin-top: 0;
	}
	h2 + h3,
	h3 + h4,
	h4 + h5,
	h5 + h6 {
		margin-top: 1.2em; /* = 1 x line-height */
	}

/** Section divider ***********************************************************/

	:not(.head) > :not(.head) + hr {
		font-size: 1.5em;
		text-align: center;
		margin: 1em auto;
		height: auto;
		color: black;
		color: var(--hr-text);
		border: transparent solid 0;
		background: transparent;
	}
	:not(.head) > hr::before {
		content: "\2727\2003\2003\2727\2003\2003\2727";
	}

/******************************************************************************/
/*                            Paragraphs and Lists                            */
/******************************************************************************/

	p {
		margin: 1em 0;
	}

	dd > p:first-child,
	li > p:first-child {
		margin-top: 0;
	}

	ul, ol {
		margin-left: 0;
		padding-left: 2em;
	}

	li {
		margin: 0.25em 0 0.5em;
		padding: 0;
	}

	dl dd {
		margin: 0 0 .5em 2em;
	}

	.head dd + dd { /* compact for header */
		margin-top: -.5em;
	}

	/* Style for algorithms */
	ol.algorithm ol:not(.algorithm),
	.algorithm > ol ol:not(.algorithm) {
	border-left: 0.5em solid #DEF;
	border-left: 0.5em solid var(--algo-border);
	}

	/* Put nice boxes around each algorithm. */
	[data-algorithm]:not(.heading) {
	 padding: .5em;
	 border: thin solid #ddd;
	 border: thin solid var(--algo-border);
	 border-radius: .5em;
	 margin: .5em calc(-0.5em - 1px);
	}
	[data-algorithm]:not(.heading) > :first-child {
	 margin-top: 0;
	}
	[data-algorithm]:not(.heading) > :last-child {
	 margin-bottom: 0;
	}

	/* Style for switch/case <dl>s */
	dl.switch > dd > ol.only,
	dl.switch > dd > .only > ol {
	margin-left: 0;
	}
	dl.switch > dd > ol.algorithm,
	dl.switch > dd > .algorithm > ol {
	margin-left: -2em;
	}
	dl.switch {
	padding-left: 2em;
	}
	dl.switch > dt {
	text-indent: -1.5em;
	margin-top: 1em;
	}
	dl.switch > dt + dt {
	margin-top: 0;
	}
	dl.switch > dt::before {
	content: '\21AA';
	padding: 0 0.5em 0 0;
	display: inline-block;
	width: 1em;
	text-align: right;
	line-height: 0.5em;
	}

/** Terminology Markup ********************************************************/


/******************************************************************************/
/*                                 Inline Markup                              */
/******************************************************************************/

/** Terminology Markup ********************************************************/
	dfn   { /* Defining instance */
		font-weight: bolder;
	}
	a > i { /* Instance of term */
		font-style: normal;
	}
	dt dfn code, code.idl {
		font-size: inherit;
	}
	dfn var {
		font-style: normal;
	}

/** Change Marking ************************************************************/

	del {
		color: #aa0000;
		color: var(--del-text);
		background: transparent;
		background: var(--del-bg);
		text-decoration: line-through;
	}
	ins {
		color: #006100;
		color: var(--ins-text);
		background: transparent;
		background: var(--ins-bg);
		text-decoration: underline;
	}

	/* for amendments (candidate/proposed changes) */

	.amendment ins, .correction ins, .addition ins,
	ins[class^=c] {
		text-decoration-style: dotted;
	}
	.amendment del, .correction del, .addition del,
	del[class^=c] {
		text-decoration-style: dotted;
	}
	.amendment.proposed ins, .correction.proposed ins, .addition.proposed ins,
	ins[class^=c].proposed {
		text-decoration-style: double;
	}
	.amendment.proposed del, .correction.proposed del, .addition.proposed del,
	del[class^=c].proposed {
		text-decoration-style: double;
	}

/** Miscellaneous improvements to inline formatting ***************************/

	sup {
		vertical-align: super;
		font-size: 80%
	}

/******************************************************************************/
/*                                    Code                                    */
/******************************************************************************/

/** General monospace/pre rules ***********************************************/

	pre, code, samp {
		font-family: Menlo, Consolas, "DejaVu Sans Mono", Monaco, monospace;
		font-size: .9em;
		hyphens: none;
		text-transform: none;
		text-align: left;
		text-align: start;
		font-variant: normal;
		orphans: 3;
		widows: 3;
		page-break-before: avoid;
	}
	pre code,
	code code {
		font-size: 100%;
	}

	pre {
		margin-top: 1em;
		margin-bottom: 1em;
		overflow: auto;
	}

/** Inline Code fragments *****************************************************/

	/* Do something nice. */

/******************************************************************************/
/*                                    Links                                   */
/******************************************************************************/

/** General Hyperlinks ********************************************************/

	/* We hyperlink a lot, so make it less intrusive */
	a[href] {
		color: #034575;
		color: var(--a-normal-text);
		text-decoration: underline #707070;
		text-decoration: underline var(--a-normal-underline);
		text-decoration-skip-ink: none;
	}
	a:visited {
		color: #034575;
		color: var(--a-visited-text);
		text-decoration-color: #bbb;
		text-decoration-color: var(--a-visited-underline);
	}

	/* Indicate interaction with the link */
	a[href]:focus,
	a[href]:hover {
		text-decoration-thickness: 2px;
	}
	a[href]:active {
		color: #c00;
		color: var(--a-active-text);
		text-decoration-color: #c00;
		text-decoration-color: var(--a-active-underline);
	}

	/* Backout above styling for W3C logo */
	.head .logo,
	.head .logo a {
		border: none;
		text-decoration: none;
		background: transparent;
	}

/******************************************************************************/
/*                                    Images                                  */
/******************************************************************************/

	img {
		border-style: none;
	}

	img, svg {
		/* Intentionally not color-scheme aware. */
		background: white;
	}

	/* For autogen numbers, add
	  .caption::before, figcaption::before { content: "Figure " counter(figure) ". "; }
	*/

	figure, .figure, .sidefigure {
		page-break-inside: avoid;
		text-align: center;
		margin: 2.5em 0;
	}
	.figure img,	.sidefigure img,	figure img,
	.figure object, .sidefigure object, figure object {
		max-width: 100%;
		margin: auto;
		height: auto;
	}
	.figure pre, .sidefigure pre, figure pre {
		text-align: left;
		display: table;
		margin: 1em auto;
	}
	.figure table, figure table {
		margin: auto;
	}
	@media screen and (min-width: 20em) {
		.sidefigure {
			float: right;
			width: 50%;
			margin: 0 0 0.5em 0.5em;
		}
	}
	.caption, figcaption, caption {
		font-style: italic;
		font-size: 90%;
	}
	.caption::before, figcaption::before, figcaption > .marker {
		font-weight: bold;
	}
	.caption, figcaption {
		counter-increment: figure;
	}

	/* DL list is indented 2em, but figure inside it is not */
	dd > .figure, dd > figure { margin-left: -2em; }

/******************************************************************************/
/*                             Colored Boxes                                  */
/******************************************************************************/

	.issue, .note, .example, .assertion, .advisement, blockquote,
	.amendment, .correction, .addition {
		margin: 1em auto;
		padding: .5em;
		border: .5em;
		border-left-style: solid;
		page-break-inside: avoid;
	}
	span.issue, span.note {
		padding: .1em .5em .15em;
		border-right-style: solid;
	}

	blockquote > :first-child,
	.note  > p:first-child,
	.issue > p:first-child,
	.amendment > p:first-child,
	.correction > p:first-child,
	.addition > p:first-child {
		margin-top: 0;
	}
	blockquote > :last-child,
	.note  > p:last-child,
	.issue > p:last-child,
	.amendment > p:last-child,
	.correction > p:last-child,
	.addition > p:last-child {
		margin-bottom: 0;
	}


	.issue::before, .issue > .marker,
	.example::before, .example > .marker,
	.note::before, .note > .marker,
	details.note > summary > .marker,
	.amendment::before, .amendment > .marker,
	details.amendment > summary > .marker,
	.addition::before, .addition > .marker,
	addition.amendment > summary > .marker,
	.correction::before, .correction > .marker,
	correction.amendment > summary > .marker
	{
		text-transform: uppercase;
		padding-right: 1em;
	}

	.example::before, .example > .marker {
		display: block;
		padding-right: 0em;
	}

/** Blockquotes ***************************************************************/

	blockquote {
		border-color: silver;
		border-color: var(--blockquote-border);
		background: transparent;
		background: var(--blockquote-bg);
		color: currentcolor;
		color: var(--blockquote-text);
	}

/** Open issue ****************************************************************/

	.issue {
		border-color: #e05252;
		border-color: var(--issue-border);
		background: #fbe9e9;
		background: var(--issue-bg);
		color: black;
		color: var(--issue-text);
		counter-increment: issue;
		overflow: auto;
	}
	.issue::before, .issue > .marker {
		color: #831616;
		color: var(--issueheading-text);
	}
	/* Add .issue::before { content: "Issue " counter(issue) " "; } for autogen numbers,
	  or use class="marker" to mark up the issue number in source. */

/** Example *******************************************************************/

	.example {
		border-color: #e0cb52;
		border-color: var(--example-border);
		background: #fcfaee;
		background: var(--example-bg);
		color: black;
		color: var(--example-text);
		counter-increment: example;
		overflow: auto;
		clear: both;
	}
	.example::before, .example > .marker {
		color: #574b0f;
		color: var(--exampleheading-text);
	}
	/* Add .example::before { content: "Example " counter(example) " "; } for autogen numbers,
	  or use class="marker" to mark up the example number in source. */

/** Non-normative Note ********************************************************/

	.note {
		border-color: #52e052;
		border-color: var(--note-border);
		background: #e9fbe9;
		background: var(--note-bg);
		color: black;
		color: var(--note-text);
		overflow: auto;
	}

	.note::before, .note > .marker,
	details.note > summary {
		color: hsl(120, 70%, 30%);
		color: var(--noteheading-text);
	}
	/* Add .note::before { content: "Note "; } for autogen label,
	  or use class="marker" to mark up the label in source. */

	details.note[open] > summary {
		border-bottom: 1px silver solid;
		border-bottom: 1px var(--notesummary-underline) solid;
	}

/** Assertion Box *************************************************************/
	/*  for assertions in algorithms */

	.assertion {
		border-color: #AAA;
		border-color: var(--assertion-border);
		background: #EEE;
		background: var(--assertion-bg);
		color: black;
		color: var(--assertion-text);
	}

/** Advisement Box ************************************************************/
	/*  for attention-grabbing normative statements */

	.advisement {
		border-color: orange;
		border-color: var(--advisement-border);
		border-style: none solid;
		background: #fec;
		background: var(--advisement-bg);
		color: black;
		color: var(--advisement-text);
	}
	strong.advisement {
		display: block;
		text-align: center;
	}
	.advisement::before, .advisement > .marker {
		color: #b35f00;
		color: var(--advisementheading-text);
	}

/** Amendment Box *************************************************************/

	.amendment, .correction, .addition {
		border-color: #330099;
		border-color: var(--amendment-border);
		background: #F5F0FF;
		background: var(--amendment-bg);
		color: black;
		color: var(--amendment-text);
	}
	.amendment.proposed, .correction.proposed, .addition.proposed {
		border-style: solid;
		border-block-width: 0.25em;
	}
	.amendment::before, .amendment > .marker,
	details.amendment > summary::before, details.amendment > summary > .marker,
	.correction::before, .correction > .marker,
	details.correction > summary::before, details.correction > summary > .marker,
	.addition::before, .addition > .marker,
	details.addition > summary::before, details.addition > summary > .marker {
		color: #220066;
		color: var(--amendmentheading-text);
	}
	.amendment.proposed::before, .amendment.proposed > .marker,
	details.amendment.proposed > summary::before, details.amendment.proposed > summary > .marker,
	.correction.proposed::before, .correction.proposed > .marker,
	details.correction.proposed > summary::before, details.correction.proposed > summary > .marker,
	.addition.proposed::before, .addition.proposed > .marker,
	details.addition.proposed > summary::before, details.addition.proposed > summary > .marker {
		font-weight: bold;
	}

/** Spec Obsoletion Notice ****************************************************/
	/* obnoxious obsoletion notice for older/abandoned specs. */

	details {
		display: block;
	}
	summary {
		font-weight: bolder;
	}

	.annoying-warning:not(details),
	details.annoying-warning:not([open]) > summary,
	details.annoying-warning[open] {
		background: hsla(40,100%,50%,0.95);
		background: var(--warning-bg);
		color: black;
		color: var(--warning-text);
		padding: .75em 1em;
		border: red;
		border: var(--warning-border);
		border-style: solid none;
		box-shadow: 0 2px 8px black;
		text-align: center;
	}
	.annoying-warning :last-child {
		margin-bottom: 0;
	}

@media not print {
	details.annoying-warning[open] {
		position: fixed;
		left: 0;
		right: 0;
		bottom: 2em;
		z-index: 1000;
	}
}

	details.annoying-warning:not([open]) > summary {
		text-align: center;
	}

/** Entity Definition Boxes ***************************************************/

	.def {
		padding: .5em 1em;
		background: #def;
		background: var(--def-bg);
		margin: 1.2em 0;
		border-left: 0.5em solid #8ccbf2;
		border-left: 0.5em solid var(--def-border);
		color: black;
		color: var(--def-text);
	}

/******************************************************************************/
/*                                    Tables                                  */
/******************************************************************************/

	th, td {
		text-align: left;
		text-align: start;
	}

/** Property/Descriptor Definition Tables *************************************/

	table.def {
		/* inherits .def box styling, see above */
		width: 100%;
		border-spacing: 0;
	}

	table.def td,
	table.def th {
		padding: 0.5em;
		vertical-align: baseline;
		border-bottom: 1px solid #bbd7e9;
		border-bottom: 1px solid var(--defrow-border);
	}

	table.def > tbody > tr:last-child th,
	table.def > tbody > tr:last-child td {
		border-bottom: 0;
	}

	table.def th {
		font-style: italic;
		font-weight: normal;
		padding-left: 1em;
		width: 3em;
	}

	/* For when values are extra-complex and need formatting for readability */
	table td.pre {
		white-space: pre-wrap;
	}

	/* A footnote at the bottom of a def table */
	table.def td.footnote {
		padding-top: 0.6em;
	}
	table.def td.footnote::before {
		content: " ";
		display: block;
		height: 0.6em;
		width: 4em;
		border-top: thin solid;
	}

/** Data tables (and properly marked-up index tables) *************************/
	/*
		<table class="data"> highlights structural relationships in a table
		when correct markup is used (e.g. thead/tbody, th vs. td, scope attribute)

		Use class="complex data" for particularly complicated tables --
		(This will draw more lines: busier, but clearer.)

		Use class="long" on table cells with paragraph-like contents
		(This will adjust text alignment accordingly.)
		Alternately use class="longlastcol" on tables, to have the last column assume "long".
	*/

	table {
		word-wrap: normal;
		overflow-wrap: normal;
		hyphens: manual;
	}

	table.data,
	table.index {
		margin: 1em auto;
		border-collapse: collapse;
		border: hidden;
		width: 100%;
	}
	table.data caption,
	table.index caption {
		max-width: 50em;
		margin: 0 auto 1em;
	}

	table.data td,  table.data th,
	table.index td, table.index th {
		padding: 0.5em 1em;
		border-width: 1px;
		border-color: silver;
		border-color: var(--datacell-border);
		border-top-style: solid;
	}

	table.data thead td:empty {
		padding: 0;
		border: 0;
	}

	table.data  thead,
	table.index thead,
	table.data  tbody,
	table.index tbody {
		border-bottom: 2px solid;
	}

	table.data colgroup,
	table.index colgroup {
		border-left: 2px solid;
	}

	table.data  tbody th:first-child,
	table.index tbody th:first-child  {
		border-right: 2px solid;
		border-top: 1px solid silver;
		border-top: 1px solid var(--datacell-border);
		padding-right: 1em;
	}

	table.data th[colspan],
	table.data td[colspan] {
		text-align: center;
	}

	table.complex.data th,
	table.complex.data td {
		border: 1px solid silver;
		border: 1px solid var(--datacell-border);
		text-align: center;
	}

	table.data.longlastcol td:last-child,
	table.data td.long {
		vertical-align: baseline;
		text-align: left;
	}

	table.data img {
		vertical-align: middle;
	}


/*
Alternate table alignment rules

	table.data,
	table.index {
		text-align: center;
	}

	table.data  thead th[scope="row"],
	table.index thead th[scope="row"] {
		text-align: right;
	}

	table.data  tbody th:first-child,
	table.index tbody th:first-child  {
		text-align: right;
	}

Possible extra rowspan handling

	table.data  tbody th[rowspan]:not([rowspan='1']),
	table.index tbody th[rowspan]:not([rowspan='1']),
	table.data  tbody td[rowspan]:not([rowspan='1']),
	table.index tbody td[rowspan]:not([rowspan='1']) {
		border-left: 1px solid silver;
	}

	table.data  tbody th[rowspan]:first-child,
	table.index tbody th[rowspan]:first-child,
	table.data  tbody td[rowspan]:first-child,
	table.index tbody td[rowspan]:first-child{
		border-left: 0;
		border-right: 1px solid silver;
	}
*/

/******************************************************************************/
/*                                  Indices                                   */
/******************************************************************************/


/** Table of Contents *********************************************************/

	.toc a {
		/* More spacing; use padding to make it part of the click target. */
		padding: 0.1rem 1px 0;
		/* Larger, more consistently-sized click target */
		display: block;
		/* Switch to using border-bottom for underlines */
		text-decoration: none;
		border-bottom: 1px solid;
		/* Reverse color scheme */
		color: black;
		color: var(--toclink-text);
		border-color: #3980b5;
		border-color: var(--toclink-underline);
	}
	.toc a:visited {
		color: black;
		color: var(--toclink-visited-text);
		border-color: #054572;
		border-color: var(--toclink-visited-underline);
	}
	.toc a:focus,
	.toc a:hover {
		background: rgba(75%, 75%, 75%, .25);
		background: var(--a-hover-bg);
		border-bottom-width: 3px;
		margin-bottom: -2px;
	}
	.toc a:not(:focus):not(:hover) {
		/* Allow colors to cascade through from link styling */
		border-bottom-color: transparent;
	}

	.toc, .toc ol, .toc ul, .toc li {
		list-style: none; /* Numbers must be inlined into source */
		/* because generated content isn't search/selectable and markers can't do multilevel yet */
		margin:  0;
		padding: 0;
	}
	.toc {
		line-height: 1.1em;
	}

	/* ToC not indented until third level, but font style & margins show hierarchy */
	.toc > li			{ font-weight: bold;   }
	.toc > li li		 { font-weight: normal; }
	.toc > li li li	  { font-size:   95%;	}
	.toc > li li li li	{ font-size:   90%;	}
	.toc > li li li li li { font-size:   85%;	}

	/* @supports not (display:grid) { */
		.toc > li			{ margin: 1.5rem 0;	}
		.toc > li li		 { margin: 0.3rem 0;	}
		.toc > li li li	  { margin-left: 2rem;   }

		/* Section numbers in a column of their own */
		.toc .secno {
			float: left;
			width: 4rem;
			white-space: nowrap;
		}
		.toc > li li li li .secno { font-size: 85%; }
		.toc > li li li li li .secno { font-size: 100%; }

		.toc li {
			clear: both;
		}

		:not(li) > .toc			 { margin-left:  5rem; }
		.toc .secno				 { margin-left: -5rem; }
		.toc > li li li .secno	  { margin-left: -7rem; }
		.toc > li li li li .secno	{ margin-left: -9rem; }
		.toc > li li li li li .secno { margin-left: -11rem; }

		/* Tighten up indentation in narrow ToCs */
		@media (max-width: 30em) {
			:not(li) > .toc			 { margin-left:  4rem; }
			.toc .secno				 { margin-left: -4rem; }
			.toc > li li li			 { margin-left:  1rem; }
			.toc > li li li .secno	  { margin-left: -5rem; }
			.toc > li li li li .secno	{ margin-left: -6rem; }
			.toc > li li li li li .secno { margin-left: -7rem; }
		}
		/* Loosen it on wide screens */
		@media screen and (min-width: 78em) {
			body:not(.toc-inline) :not(li) > .toc			 { margin-left:  4rem; }
			body:not(.toc-inline) .toc .secno				 { margin-left: -4rem; }
			body:not(.toc-inline) .toc > li li li			 { margin-left:  1rem; }
			body:not(.toc-inline) .toc > li li li .secno	  { margin-left: -5rem; }
			body:not(.toc-inline) .toc > li li li li .secno	{ margin-left: -6rem; }
			body:not(.toc-inline) .toc > li li li li li .secno { margin-left: -7rem; }
	}
	/* } */

	@supports (display:grid) and (display:contents) {
		/* Use #toc over .toc to override non-@supports rules. */
		#toc {
			display: grid;
			align-content: start;
			grid-template-columns: auto 1fr;
			grid-column-gap: 1rem;
			column-gap: 1rem;
			grid-row-gap: .6rem;
			row-gap: .6rem;
		}
		#toc h2 {
			grid-column: 1 / -1;
			margin-bottom: 0;
		}
		#toc ol,
		#toc li,
		#toc a {
			display: contents;
			/* Switch <a> to subgrid when supported */
		}
		#toc span {
			margin: 0;
		}
		#toc > .toc > li > a > span {
			/* The spans of the top-level list,
			  comprising the first items of each top-level section. */
			margin-top: 1.1rem;
		}
		#toc#toc .secno { /* Ugh, need more specificity to override base.css */
			grid-column: 1;
			width: auto;
			margin-left: 0;
		}
		#toc .content {
			grid-column: 2;
			width: auto;
			margin-right: 1rem;
			border-bottom: 3px solid transparent;
			margin-bottom: -3px;
		}
		#toc .content:hover,
		#toc .content:focus {
			background: rgba(75%, 75%, 75%, .25);
			background: var(--a-hover-bg);
			border-bottom-color: #054572;
			border-bottom-color: var(--toclink-underline);
		}
		#toc li li li .content {
			margin-left: 1rem;
		}
		#toc li li li li .content {
			margin-left: 2rem;
		}
	}


/** Index *********************************************************************/

	/* Index Lists: Layout */
	ul.index	  { margin-left: 0; columns: 15em; text-indent: 1em hanging; }
	ul.index li	{ margin-left: 0; list-style: none; break-inside: avoid; }
	ul.index li li { margin-left: 1em; }
	ul.index dl	{ margin-top: 0; }
	ul.index dt	{ margin: .2em 0 .2em 20px;}
	ul.index dd	{ margin: .2em 0 .2em 40px;}
	/* Index Lists: Typography */
	ul.index ul,
	ul.index dl { font-size: smaller; }
	@media not print {
		ul.index li a + span {
			white-space: nowrap;
			color: transparent; }
		ul.index li a:hover + span,
		ul.index li a:focus + span {
			color: #707070;
			color: var(--indexinfo-text);
		}
	}

/** Index Tables *****************************************************/
	/* See also the data table styling section, which this effectively subclasses */

	table.index {
		font-size: small;
		border-collapse: collapse;
		border-spacing: 0;
		text-align: left;
		margin: 1em 0;
	}

	table.index td,
	table.index th {
		padding: 0.4em;
	}

	table.index tr:hover td:not([rowspan]),
	table.index tr:hover th:not([rowspan]) {
		color: black;
		color: var(--indextable-hover-text);
		background: #f7f8f9;
		background: var(--indextable-hover-bg);
	}

	/* The link in the first column in the property table (formerly a TD) */
	table.index th:first-child a {
		font-weight: bold;
	}

/** Outdated warning **********************************************************/

.outdated-spec {
	color: black;
	color: var(--outdatedspec-text);
	background-color: rgba(0,0,0,0.5);
	background-color: var(--outdatedspec-bg);
}

.outdated-warning {
	position: fixed;
	bottom: 50%;
	left: 0;
	right: 0;
	margin: 0 auto;
	width: 50%;
	background: maroon;
	background: var(--outdated-bg);
	color: white;
	color: var(--outdated-text);
	border-radius: 1em;
	box-shadow: 0 0 1em red;
	box-shadow: 0 0 1em var(--outdated-shadow);
	padding: 2em;
	text-align: center;
	z-index: 2;
}

.outdated-warning a {
	color: currentcolor;
	background: transparent;
}

.edited-rec-warning {
	background: darkorange;
	background: var(--editedrec-bg);
	box-shadow: 0 0 1em;
}

.outdated-warning button {
	color: var(--outdated-text);
	border-radius: 1em;
	box-shadow: 0 0 1em red;
	box-shadow: 0 0 1em var(--outdated-shadow);
	padding: 2em;
	text-align: center;
	z-index: 2;
}

.outdated-warning a {
	color: currentcolor;
	background: transparent;
}

.edited-rec-warning {
	background: darkorange;
	background: var(--editedrec-bg);
	box-shadow: 0 0 1em;
}

.outdated-warning button {
	position: absolute;
	top: 0;
	right:0;
	margin: 0;
	border: 0;
	padding: 0.25em 0.5em;
	background: transparent;
	color: white;
	color: var(--outdated-text);
	font:1em sans-serif;
	text-align:center;
}

.outdated-warning span {
	display: block;
}

.outdated-collapsed {
	bottom: 0;
	border-radius: 0;
	width: 100%;
	padding: 0;
}

/******************************************************************************/
/*                                    Print                                   */
/******************************************************************************/

	@media print {
		/* Pages have their own margins. */
		html {
			margin: 0;
		}
		/* Serif for print. */
		body {
			font-family: serif;
		}

		.outdated-warning {
			position: absolute;
			border-style: solid;
			border-color: red;
		}

		.outdated-warning input {
			display: none;
		}
	}
	@page {
		margin: 1.5cm 1.1cm;
	}



/******************************************************************************/
/*                             Overflow Control                               */
/******************************************************************************/

	.figure .caption, .sidefigure .caption, figcaption {
		/* in case figure is overlarge, limit caption to 50em */
		max-width: 50rem;
		margin-left: auto;
		margin-right: auto;
	}
	.overlarge {
		/* Magic to create good item positioning:
		  "content column" is 50ems wide at max; less on smaller screens.
		  Extra space (after ToC + content) is empty on the right.

		  1. When item < content column, centers item in column.
		  2. When content < item < available, left-aligns.
		  3. When item > available, fills available + scroll bar.
		*/
		display: grid;
		grid-template-columns: minmax(0, 50em);
	}
	.overlarge > table {
		/* limit preferred width of table */
		max-width: 50em;
		margin-left: auto;
		margin-right: auto;
	}

	@media (min-width: 55em) {
		.overlarge {
			margin-right: calc(13px + 26.5rem - 50vw);
			max-width: none;
		}
	}
	@media screen and (min-width: 78em) {
		body:not(.toc-inline) .overlarge {
			/* 30.5em body padding 50em content area */
			margin-right: calc(40em - 50vw) !important;
		}
	}
	@media screen and (min-width: 90em) {
		body:not(.toc-inline) .overlarge {
			/* 4em html margin 30.5em body padding 50em content area */
			margin-right: calc(84.5em - 100vw) !important;
		}
	}

	@media not print {
		.overlarge {
			overflow-x: auto;
			/* See Lea Verou's explanation background-attachment:
			* http://lea.verou.me/2012/04/background-attachment-local/
			*
			background: top left  / 4em 100% linear-gradient(to right,  #ffffff, rgba(255, 255, 255, 0)) local,
						top right / 4em 100% linear-gradient(to left, #ffffff, rgba(255, 255, 255, 0)) local,
						top left  / 1em 100% linear-gradient(to right,  #c3c3c5, rgba(195, 195, 197, 0)) scroll,
						top right / 1em 100% linear-gradient(to left, #c3c3c5, rgba(195, 195, 197, 0)) scroll,
						white;
			background-repeat: no-repeat;
			*/
		}
	}
</style>
<style>
    table, th, td {
      border: 1px solid black;
      border-collapse: collapse;
      vertical-align: top;
    }
    th, td {
      border-left: none;
      border-right: none;
      padding: 0px 10px;
    }
    th {
      text-align: center;
    }

    del { background: #fcc; color: #000; text-decoration: line-through; }
    ins { background: #cfc; color: #000; }
    blockquote .highlight:not(.idl) { background: initial; margin: initial; padding: 0.5em }
    blockquote ul { background: inherit; }
    blockquote code.highlight:not(.idl) { padding: initial; }
    blockquote c-[a] { color: inherit; } /* Keyword.Declaration */
    blockquote c-[b] { color: inherit; } /* Keyword.Type */
    blockquote c-[c] { color: inherit; } /* Comment */
    blockquote c-[d] { color: inherit; } /* Comment.Multiline */
    blockquote c-[e] { color: inherit; } /* Name.Attribute */
    blockquote c-[f] { color: inherit; } /* Name.Tag */
    blockquote c-[g] { color: inherit; } /* Name.Variable */
    blockquote c-[k] { color: inherit; } /* Keyword */
    blockquote c-[l] { color: inherit; } /* Literal */
    blockquote c-[m] { color: inherit; } /* Literal.Number */
    blockquote c-[n] { color: inherit; } /* Name */
    blockquote c-[o] { color: inherit; } /* Operator */
    blockquote c-[p] { color: inherit; } /* Punctuation */
    blockquote c-[s] { color: inherit; } /* Literal.String */
    blockquote c-[t] { color: inherit; } /* Literal.String.Single */
    blockquote c-[u] { color: inherit; } /* Literal.String.Double */
    blockquote c-[cp] { color: inherit; } /* Comment.Preproc */
    blockquote c-[c1] { color: inherit; } /* Comment.Single */
    blockquote c-[cs] { color: inherit; } /* Comment.Special */
    blockquote c-[kc] { color: inherit; } /* Keyword.Constant */
    blockquote c-[kn] { color: inherit; } /* Keyword.Namespace */
    blockquote c-[kp] { color: inherit; } /* Keyword.Pseudo */
    blockquote c-[kr] { color: inherit; } /* Keyword.Reserved */
    blockquote c-[ld] { color: inherit; } /* Literal.Date */
    blockquote c-[nc] { color: inherit; } /* Name.Class */
    blockquote c-[no] { color: inherit; } /* Name.Constant */
    blockquote c-[nd] { color: inherit; } /* Name.Decorator */
    blockquote c-[ni] { color: inherit; } /* Name.Entity */
    blockquote c-[ne] { color: inherit; } /* Name.Exception */
    blockquote c-[nf] { color: inherit; } /* Name.Function */
    blockquote c-[nl] { color: inherit; } /* Name.Label */
    blockquote c-[nn] { color: inherit; } /* Name.Namespace */
    blockquote c-[py] { color: inherit; } /* Name.Property */
    blockquote c-[ow] { color: inherit; } /* Operator.Word */
    blockquote c-[mb] { color: inherit; } /* Literal.Number.Bin */
    blockquote c-[mf] { color: inherit; } /* Literal.Number.Float */
    blockquote c-[mh] { color: inherit; } /* Literal.Number.Hex */
    blockquote c-[mi] { color: inherit; } /* Literal.Number.Integer */
    blockquote c-[mo] { color: inherit; } /* Literal.Number.Oct */
    blockquote c-[sb] { color: inherit; } /* Literal.String.Backtick */
    blockquote c-[sc] { color: inherit; } /* Literal.String.Char */
    blockquote c-[sd] { color: inherit; } /* Literal.String.Doc */
    blockquote c-[se] { color: inherit; } /* Literal.String.Escape */
    blockquote c-[sh] { color: inherit; } /* Literal.String.Heredoc */
    blockquote c-[si] { color: inherit; } /* Literal.String.Interpol */
    blockquote c-[sx] { color: inherit; } /* Literal.String.Other */
    blockquote c-[sr] { color: inherit; } /* Literal.String.Regex */
    blockquote c-[ss] { color: inherit; } /* Literal.String.Symbol */
    blockquote c-[vc] { color: inherit; } /* Name.Variable.Class */
    blockquote c-[vg] { color: inherit; } /* Name.Variable.Global */
    blockquote c-[vi] { color: inherit; } /* Name.Variable.Instance */
    blockquote c-[il] { color: inherit; } /* Literal.Number.Integer.Long */
  </style>
  <meta content="Bikeshed version ac5ea272d, updated Fri Dec 6 15:45:15 2024 -0800" name="generator">
  <link href="https://isocpp.org/favicon.ico" rel="icon">
  <meta content="dark light" name="color-scheme">
<style>
p    {-moz-hyphens: none; -ms-hyphens: none; -webkit-hyphens: none; hyphens: none;}
ins  {background-color: #CCFFCC; text-decoration: underline;}
del  {background-color: #FFCACA; text-decoration: line-through;}
</style>
<style>/* Boilerplate: style-autolinks */
.css.css, .property.property, .descriptor.descriptor {
    color: var(--a-normal-text);
    font-size: inherit;
    font-family: inherit;
}
.css::before, .property::before, .descriptor::before {
    content: "‘";
}
.css::after, .property::after, .descriptor::after {
    content: "’";
}
.property, .descriptor {
    /* Don't wrap property and descriptor names */
    white-space: nowrap;
}
.type { /* CSS value <type> */
    font-style: italic;
}
pre .property::before, pre .property::after {
    content: "";
}
[data-link-type="property"]::before,
[data-link-type="propdesc"]::before,
[data-link-type="descriptor"]::before,
[data-link-type="value"]::before,
[data-link-type="function"]::before,
[data-link-type="at-rule"]::before,
[data-link-type="selector"]::before,
[data-link-type="maybe"]::before {
    content: "‘";
}
[data-link-type="property"]::after,
[data-link-type="propdesc"]::after,
[data-link-type="descriptor"]::after,
[data-link-type="value"]::after,
[data-link-type="function"]::after,
[data-link-type="at-rule"]::after,
[data-link-type="selector"]::after,
[data-link-type="maybe"]::after {
    content: "’";
}

[data-link-type].production::before,
[data-link-type].production::after,
.prod [data-link-type]::before,
.prod [data-link-type]::after {
    content: "";
}

[data-link-type=element],
[data-link-type=element-attr] {
    font-family: Menlo, Consolas, "DejaVu Sans Mono", monospace;
    font-size: .9em;
}
[data-link-type=element]::before { content: "<" }
[data-link-type=element]::after  { content: ">" }

[data-link-type=biblio] {
    white-space: pre;
}

@media (prefers-color-scheme: dark) {
    :root {
        --selflink-text: black;
        --selflink-bg: silver;
        --selflink-hover-text: white;
    }
}
</style>
<style>/* Boilerplate: style-colors */
/* Any --*-text not paired with a --*-bg is assumed to have a transparent bg */
:root {
    color-scheme: light dark;

    --text: black;
    --bg: white;

    --unofficial-watermark: url(https://www.w3.org/StyleSheets/TR/2016/logos/UD-watermark);

    --logo-bg: #1a5e9a;
    --logo-active-bg: #c00;
    --logo-text: white;

    --tocnav-normal-text: #707070;
    --tocnav-normal-bg: var(--bg);
    --tocnav-hover-text: var(--tocnav-normal-text);
    --tocnav-hover-bg: #f8f8f8;
    --tocnav-active-text: #c00;
    --tocnav-active-bg: var(--tocnav-normal-bg);

    --tocsidebar-text: var(--text);
    --tocsidebar-bg: #f7f8f9;
    --tocsidebar-shadow: rgba(0,0,0,.1);
    --tocsidebar-heading-text: hsla(203,20%,40%,.7);

    --toclink-text: var(--text);
    --toclink-underline: #3980b5;
    --toclink-visited-text: var(--toclink-text);
    --toclink-visited-underline: #054572;

    --heading-text: #005a9c;

    --hr-text: var(--text);

    --algo-border: #def;

    --del-text: red;
    --del-bg: transparent;
    --ins-text: #080;
    --ins-bg: transparent;

    --a-normal-text: #034575;
    --a-normal-underline: #bbb;
    --a-visited-text: var(--a-normal-text);
    --a-visited-underline: #707070;
    --a-hover-bg: rgba(75%, 75%, 75%, .25);
    --a-active-text: #c00;
    --a-active-underline: #c00;

    --blockquote-border: silver;
    --blockquote-bg: transparent;
    --blockquote-text: currentcolor;

    --issue-border: #e05252;
    --issue-bg: #fbe9e9;
    --issue-text: var(--text);
    --issueheading-text: #831616;

    --example-border: #e0cb52;
    --example-bg: #fcfaee;
    --example-text: var(--text);
    --exampleheading-text: #574b0f;

    --note-border: #52e052;
    --note-bg: #e9fbe9;
    --note-text: var(--text);
    --noteheading-text: hsl(120, 70%, 30%);
    --notesummary-underline: silver;

    --assertion-border: #aaa;
    --assertion-bg: #eee;
    --assertion-text: black;

    --advisement-border: orange;
    --advisement-bg: #fec;
    --advisement-text: var(--text);
    --advisementheading-text: #b35f00;

    --warning-border: red;
    --warning-bg: hsla(40,100%,50%,0.95);
    --warning-text: var(--text);

    --amendment-border: #330099;
    --amendment-bg: #F5F0FF;
    --amendment-text: var(--text);
    --amendmentheading-text: #220066;

    --def-border: #8ccbf2;
    --def-bg: #def;
    --def-text: var(--text);
    --defrow-border: #bbd7e9;

    --datacell-border: silver;

    --indexinfo-text: #707070;

    --indextable-hover-text: black;
    --indextable-hover-bg: #f7f8f9;

    --outdatedspec-bg: rgba(0, 0, 0, .5);
    --outdatedspec-text: black;
    --outdated-bg: maroon;
    --outdated-text: white;
    --outdated-shadow: red;

    --editedrec-bg: darkorange;
}

@media (prefers-color-scheme: dark) {
    :root {
        --text: #ddd;
        --bg: black;

        --unofficial-watermark: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='400' height='400'%3E%3Cg fill='%23100808' transform='translate(200 200) rotate(-45) translate(-200 -200)' stroke='%23100808' stroke-width='3'%3E%3Ctext x='50%25' y='220' style='font: bold 70px sans-serif; text-anchor: middle; letter-spacing: 6px;'%3EUNOFFICIAL%3C/text%3E%3Ctext x='50%25' y='305' style='font: bold 70px sans-serif; text-anchor: middle; letter-spacing: 6px;'%3EDRAFT%3C/text%3E%3C/g%3E%3C/svg%3E");

        --logo-bg: #1a5e9a;
        --logo-active-bg: #c00;
        --logo-text: white;

        --tocnav-normal-text: #999;
        --tocnav-normal-bg: var(--bg);
        --tocnav-hover-text: var(--tocnav-normal-text);
        --tocnav-hover-bg: #080808;
        --tocnav-active-text: #f44;
        --tocnav-active-bg: var(--tocnav-normal-bg);

        --tocsidebar-text: var(--text);
        --tocsidebar-bg: #080808;
        --tocsidebar-shadow: rgba(255,255,255,.1);
        --tocsidebar-heading-text: hsla(203,20%,40%,.7);

        --toclink-text: var(--text);
        --toclink-underline: #6af;
        --toclink-visited-text: var(--toclink-text);
        --toclink-visited-underline: #054572;

        --heading-text: #8af;

        --hr-text: var(--text);

        --algo-border: #456;

        --del-text: #f44;
        --del-bg: transparent;
        --ins-text: #4a4;
        --ins-bg: transparent;

        --a-normal-text: #6af;
        --a-normal-underline: #555;
        --a-visited-text: var(--a-normal-text);
        --a-visited-underline: var(--a-normal-underline);
        --a-hover-bg: rgba(25%, 25%, 25%, .2);
        --a-active-text: #f44;
        --a-active-underline: var(--a-active-text);

        --borderedblock-bg: rgba(255, 255, 255, .05);

        --blockquote-border: silver;
        --blockquote-bg: var(--borderedblock-bg);
        --blockquote-text: currentcolor;

        --issue-border: #e05252;
        --issue-bg: var(--borderedblock-bg);
        --issue-text: var(--text);
        --issueheading-text: hsl(0deg, 70%, 70%);

        --example-border: hsl(50deg, 90%, 60%);
        --example-bg: var(--borderedblock-bg);
        --example-text: var(--text);
        --exampleheading-text: hsl(50deg, 70%, 70%);

        --note-border: hsl(120deg, 100%, 35%);
        --note-bg: var(--borderedblock-bg);
        --note-text: var(--text);
        --noteheading-text: hsl(120, 70%, 70%);
        --notesummary-underline: silver;

        --assertion-border: #444;
        --assertion-bg: var(--borderedblock-bg);
        --assertion-text: var(--text);

        --advisement-border: orange;
        --advisement-bg: #222218;
        --advisement-text: var(--text);
        --advisementheading-text: #f84;

        --warning-border: red;
        --warning-bg: hsla(40,100%,20%,0.95);
        --warning-text: var(--text);

        --amendment-border: #330099;
        --amendment-bg: #080010;
        --amendment-text: var(--text);
        --amendmentheading-text: #cc00ff;

        --def-border: #8ccbf2;
        --def-bg: #080818;
        --def-text: var(--text);
        --defrow-border: #136;

        --datacell-border: silver;

        --indexinfo-text: #aaa;

        --indextable-hover-text: var(--text);
        --indextable-hover-bg: #181818;

        --outdatedspec-bg: rgba(255, 255, 255, .5);
        --outdatedspec-text: black;
        --outdated-bg: maroon;
        --outdated-text: white;
        --outdated-shadow: red;

        --editedrec-bg: darkorange;
    }
    /* In case a transparent-bg image doesn't expect to be on a dark bg,
       which is quite common in practice... */
    img { background: white; }
}
</style>
<style>/* Boilerplate: style-counters */
body {
    counter-reset: example figure issue;
}
.issue {
    counter-increment: issue;
}
.issue:not(.no-marker)::before {
    content: "Issue " counter(issue);
}

.example {
    counter-increment: example;
}
.example:not(.no-marker)::before {
    content: "Example " counter(example);
}
.invalid.example:not(.no-marker)::before,
.illegal.example:not(.no-marker)::before {
    content: "Invalid Example" counter(example);
}

figcaption {
    counter-increment: figure;
}
figcaption:not(.no-marker)::before {
    content: "Figure " counter(figure) " ";
}
</style>
<style>/* Boilerplate: style-issues */
a[href].issue-return {
    float: right;
    float: inline-end;
    color: var(--issueheading-text);
    font-weight: bold;
    text-decoration: none;
}
</style>
<style>/* Boilerplate: style-md-lists */
/* This is a weird hack for me not yet following the commonmark spec
   regarding paragraph and lists. */
[data-md] > :first-child {
    margin-top: 0;
}
[data-md] > :last-child {
    margin-bottom: 0;
}
</style>
<style>/* Boilerplate: style-selflinks */
:root {
    --selflink-text: white;
    --selflink-bg: gray;
    --selflink-hover-text: black;
}
.heading, .issue, .note, .example, li, dt {
    position: relative;
}
a.self-link {
    position: absolute;
    top: 0;
    left: calc(-1 * (3.5rem - 26px));
    width: calc(3.5rem - 26px);
    height: 2em;
    text-align: center;
    border: none;
    transition: opacity .2s;
    opacity: .5;
}
a.self-link:hover {
    opacity: 1;
}
.heading > a.self-link {
    font-size: 83%;
}
.example > a.self-link,
.note > a.self-link,
.issue > a.self-link {
    /* These blocks are overflow:auto, so positioning outside
       doesn't work. */
    left: auto;
    right: 0;
}
li > a.self-link {
    left: calc(-1 * (3.5rem - 26px) - 2em);
}
dfn > a.self-link {
    top: auto;
    left: auto;
    opacity: 0;
    width: 1.5em;
    height: 1.5em;
    background: var(--selflink-bg);
    color: var(--selflink-text);
    font-style: normal;
    transition: opacity .2s, background-color .2s, color .2s;
}
dfn:hover > a.self-link {
    opacity: 1;
}
dfn > a.self-link:hover {
    color: var(--selflink-hover-text);
}

a.self-link::before            { content: "¶"; }
.heading > a.self-link::before { content: "§"; }
dfn > a.self-link::before      { content: "#"; }
</style>
<style>/* Boilerplate: style-syntax-highlighting */
code.highlight { padding: .1em; border-radius: .3em; }
pre.highlight, pre > code.highlight { display: block; padding: 1em; margin: .5em 0; overflow: auto; border-radius: 0; }

.highlight:not(.idl) { background: rgba(0, 0, 0, .03); }
c-[a] { color: #990055 } /* Keyword.Declaration */
c-[b] { color: #990055 } /* Keyword.Type */
c-[c] { color: #708090 } /* Comment */
c-[d] { color: #708090 } /* Comment.Multiline */
c-[e] { color: #0077aa } /* Name.Attribute */
c-[f] { color: #669900 } /* Name.Tag */
c-[g] { color: #222222 } /* Name.Variable */
c-[k] { color: #990055 } /* Keyword */
c-[l] { color: #000000 } /* Literal */
c-[m] { color: #000000 } /* Literal.Number */
c-[n] { color: #0077aa } /* Name */
c-[o] { color: #999999 } /* Operator */
c-[p] { color: #999999 } /* Punctuation */
c-[s] { color: #a67f59 } /* Literal.String */
c-[t] { color: #a67f59 } /* Literal.String.Single */
c-[u] { color: #a67f59 } /* Literal.String.Double */
c-[cp] { color: #708090 } /* Comment.Preproc */
c-[c1] { color: #708090 } /* Comment.Single */
c-[cs] { color: #708090 } /* Comment.Special */
c-[kc] { color: #990055 } /* Keyword.Constant */
c-[kn] { color: #990055 } /* Keyword.Namespace */
c-[kp] { color: #990055 } /* Keyword.Pseudo */
c-[kr] { color: #990055 } /* Keyword.Reserved */
c-[ld] { color: #000000 } /* Literal.Date */
c-[nc] { color: #0077aa } /* Name.Class */
c-[no] { color: #0077aa } /* Name.Constant */
c-[nd] { color: #0077aa } /* Name.Decorator */
c-[ni] { color: #0077aa } /* Name.Entity */
c-[ne] { color: #0077aa } /* Name.Exception */
c-[nf] { color: #0077aa } /* Name.Function */
c-[nl] { color: #0077aa } /* Name.Label */
c-[nn] { color: #0077aa } /* Name.Namespace */
c-[py] { color: #0077aa } /* Name.Property */
c-[ow] { color: #999999 } /* Operator.Word */
c-[mb] { color: #000000 } /* Literal.Number.Bin */
c-[mf] { color: #000000 } /* Literal.Number.Float */
c-[mh] { color: #000000 } /* Literal.Number.Hex */
c-[mi] { color: #000000 } /* Literal.Number.Integer */
c-[mo] { color: #000000 } /* Literal.Number.Oct */
c-[sb] { color: #a67f59 } /* Literal.String.Backtick */
c-[sc] { color: #a67f59 } /* Literal.String.Char */
c-[sd] { color: #a67f59 } /* Literal.String.Doc */
c-[se] { color: #a67f59 } /* Literal.String.Escape */
c-[sh] { color: #a67f59 } /* Literal.String.Heredoc */
c-[si] { color: #a67f59 } /* Literal.String.Interpol */
c-[sx] { color: #a67f59 } /* Literal.String.Other */
c-[sr] { color: #a67f59 } /* Literal.String.Regex */
c-[ss] { color: #a67f59 } /* Literal.String.Symbol */
c-[vc] { color: #0077aa } /* Name.Variable.Class */
c-[vg] { color: #0077aa } /* Name.Variable.Global */
c-[vi] { color: #0077aa } /* Name.Variable.Instance */
c-[il] { color: #000000 } /* Literal.Number.Integer.Long */

@media (prefers-color-scheme: dark) {
    .highlight:not(.idl) { background: rgba(255, 255, 255, .05); }

    c-[a] { color: #d33682 } /* Keyword.Declaration */
    c-[b] { color: #d33682 } /* Keyword.Type */
    c-[c] { color: #2aa198 } /* Comment */
    c-[d] { color: #2aa198 } /* Comment.Multiline */
    c-[e] { color: #268bd2 } /* Name.Attribute */
    c-[f] { color: #b58900 } /* Name.Tag */
    c-[g] { color: #cb4b16 } /* Name.Variable */
    c-[k] { color: #d33682 } /* Keyword */
    c-[l] { color: #657b83 } /* Literal */
    c-[m] { color: #657b83 } /* Literal.Number */
    c-[n] { color: #268bd2 } /* Name */
    c-[o] { color: #657b83 } /* Operator */
    c-[p] { color: #657b83 } /* Punctuation */
    c-[s] { color: #6c71c4 } /* Literal.String */
    c-[t] { color: #6c71c4 } /* Literal.String.Single */
    c-[u] { color: #6c71c4 } /* Literal.String.Double */
    c-[ch] { color: #2aa198 } /* Comment.Hashbang */
    c-[cp] { color: #2aa198 } /* Comment.Preproc */
    c-[cpf] { color: #2aa198 } /* Comment.PreprocFile */
    c-[c1] { color: #2aa198 } /* Comment.Single */
    c-[cs] { color: #2aa198 } /* Comment.Special */
    c-[kc] { color: #d33682 } /* Keyword.Constant */
    c-[kn] { color: #d33682 } /* Keyword.Namespace */
    c-[kp] { color: #d33682 } /* Keyword.Pseudo */
    c-[kr] { color: #d33682 } /* Keyword.Reserved */
    c-[ld] { color: #657b83 } /* Literal.Date */
    c-[nc] { color: #268bd2 } /* Name.Class */
    c-[no] { color: #268bd2 } /* Name.Constant */
    c-[nd] { color: #268bd2 } /* Name.Decorator */
    c-[ni] { color: #268bd2 } /* Name.Entity */
    c-[ne] { color: #268bd2 } /* Name.Exception */
    c-[nf] { color: #268bd2 } /* Name.Function */
    c-[nl] { color: #268bd2 } /* Name.Label */
    c-[nn] { color: #268bd2 } /* Name.Namespace */
    c-[py] { color: #268bd2 } /* Name.Property */
    c-[ow] { color: #657b83 } /* Operator.Word */
    c-[mb] { color: #657b83 } /* Literal.Number.Bin */
    c-[mf] { color: #657b83 } /* Literal.Number.Float */
    c-[mh] { color: #657b83 } /* Literal.Number.Hex */
    c-[mi] { color: #657b83 } /* Literal.Number.Integer */
    c-[mo] { color: #657b83 } /* Literal.Number.Oct */
    c-[sa] { color: #6c71c4 } /* Literal.String.Affix */
    c-[sb] { color: #6c71c4 } /* Literal.String.Backtick */
    c-[sc] { color: #6c71c4 } /* Literal.String.Char */
    c-[dl] { color: #6c71c4 } /* Literal.String.Delimiter */
    c-[sd] { color: #6c71c4 } /* Literal.String.Doc */
    c-[se] { color: #6c71c4 } /* Literal.String.Escape */
    c-[sh] { color: #6c71c4 } /* Literal.String.Heredoc */
    c-[si] { color: #6c71c4 } /* Literal.String.Interpol */
    c-[sx] { color: #6c71c4 } /* Literal.String.Other */
    c-[sr] { color: #6c71c4 } /* Literal.String.Regex */
    c-[ss] { color: #6c71c4 } /* Literal.String.Symbol */
    c-[fm] { color: #268bd2 } /* Name.Function.Magic */
    c-[vc] { color: #cb4b16 } /* Name.Variable.Class */
    c-[vg] { color: #cb4b16 } /* Name.Variable.Global */
    c-[vi] { color: #cb4b16 } /* Name.Variable.Instance */
    c-[vm] { color: #cb4b16 } /* Name.Variable.Magic */
    c-[il] { color: #657b83 } /* Literal.Number.Integer.Long */
}
</style>
 <body class="h-entry">
  <div class="head">
   <p data-fill-with="logo"></p>
   <h1 class="p-name no-ref" id="title">P2952R2<br>auto&amp; operator=(X&amp;&amp;) = default</h1>
   <h2 class="no-num no-toc no-ref heading settled" id="profile-and-date"><span class="content">Published Proposal, <time class="dt-updated" datetime="2025-01-08">2025-01-08</time></span></h2>
   <div data-fill-with="spec-metadata">
    <dl>
     <dt class="editor">Authors:
     <dd class="editor p-author h-card vcard"><a class="p-name fn u-email email" href="mailto:arthur.j.odwyer@gmail.com">Arthur O'Dwyer</a>
     <dd class="editor p-author h-card vcard"><a class="p-name fn u-email email" href="mailto:mjtaylor214@hotmail.com">Matthew Taylor</a>
     <dt>Audience:
     <dd>CWG
     <dt>Project:
     <dd>ISO/IEC 14882 Programming Languages — C++, ISO/IEC JTC1/SC22/WG21
    </dl>
   </div>
   <div data-fill-with="warning"></div>
   <hr title="Separator for header">
  </div>
  <div class="p-summary" data-fill-with="abstract">
   <h2 class="no-num no-toc no-ref heading settled" id="abstract"><span class="content">Abstract</span></h2>
   <p>Current C++ forbids explicitly defaulted functions to have placeholder return types such as <code class="highlight"><c- k>auto</c-><c- o>&amp;</c-></code>,
except for C++20’s <code class="highlight"><c- k>operator</c-><c- o>&lt;=></c-></code>. We remove this syntactic restriction
in cases where the deduced return type would be the same as the expected one.
This allows more consistency and less repetition when declaring defaulted functions.</p>
  </div>
  <nav data-fill-with="table-of-contents" id="toc">
   <h2 class="no-num no-toc no-ref" id="contents">Table of Contents</h2>
   <ol class="toc" role="directory">
    <li><a href="#changelog"><span class="secno">1</span> <span class="content">Changelog</span></a>
    <li><a href="#motivation"><span class="secno">2</span> <span class="content">Motivation</span></a>
    <li>
     <a href="#proposal"><span class="secno">3</span> <span class="content">Proposal</span></a>
     <ol class="toc">
      <li><a href="#declared-type"><span class="secno">3.1</span> <span class="content">"Return type" versus "declared return type"</span></a>
      <li><a href="#defaulted-as-deleted"><span class="secno">3.2</span> <span class="content">"Defaulted as deleted"</span></a>
      <li><a href="#deducing-this"><span class="secno">3.3</span> <span class="content">"Deducing <code class="highlight"><c- k>this</c-></code>" and CWG2586</span></a>
      <li><a href="#new-burden"><span class="secno">3.4</span> <span class="content">Burden on specifying new defaultable operators</span></a>
      <li><a href="#other-return-types"><span class="secno">3.5</span> <span class="content">Other return types are still forbidden</span></a>
      <li><a href="#corner-cases"><span class="secno">3.6</span> <span class="content">Existing corner cases</span></a>
      <li><a href="#impact"><span class="secno">3.7</span> <span class="content">Impact on existing code</span></a>
     </ol>
    <li><a href="#experience"><span class="secno">4</span> <span class="content">Implementation experience</span></a>
    <li><a href="#polls"><span class="secno">5</span> <span class="content">Straw poll results</span></a>
    <li>
     <a href="#wording"><span class="secno">6</span> <span class="content">Proposed wording</span></a>
     <ol class="toc">
      <li><a href="#wording-class.eq"><span class="secno">6.1</span> <span class="content">[class.eq]</span></a>
      <li><a href="#wording-class.spaceship"><span class="secno">6.2</span> <span class="content">[class.spaceship]</span></a>
      <li><a href="#wording-class.compare.secondary"><span class="secno">6.3</span> <span class="content">[class.compare.secondary]</span></a>
      <li><a href="#wording-class.copy.assign"><span class="secno">6.4</span> <span class="content">[class.copy.assign]</span></a>
     </ol>
    <li>
     <a href="#references"><span class="secno"></span> <span class="content">References</span></a>
     <ol class="toc">
      <li><a href="#informative"><span class="secno"></span> <span class="content">Informative References</span></a>
     </ol>
   </ol>
  </nav>
  <main>
   <h2 class="heading settled" data-level="1" id="changelog"><span class="secno">1. </span><span class="content">Changelog</span><a class="self-link" href="#changelog"></a></h2>
   <ul>
    <li data-md>
     <p>R2 (pre-Hagenberg):</p>
     <ul>
      <li data-md>
       <p>Forward to CWG (see <a href="#polls">§ 5 Straw poll results</a>).</p>
      <li data-md>
       <p>Fix one mistake in a drafting note ("deleted" to "ill-formed").</p>
     </ul>
    <li data-md>
     <p>R1:</p>
     <ul>
      <li data-md>
       <p>Add discussion of <code class="highlight"><c- b>void</c-> <c- k>operator</c-><c- o>=</c-><c- p>(</c-><c- n>X</c-><c- o>&amp;&amp;</c-><c- p>)</c-> <c- o>=</c-> <c- k>default</c-></code>, and of triviality, in <a href="#other-return-types">§ 3.5 Other return types are still forbidden</a>.</p>
     </ul>
   </ul>
   <h2 class="heading settled" data-level="2" id="motivation"><span class="secno">2. </span><span class="content">Motivation</span><a class="self-link" href="#motivation"></a></h2>
   <p>Current C++ permits <code class="highlight"><c- o>=</c-><c- k>default</c-></code> to appear only on certain signatures, with certain return types.
The current wording prohibits the use of placeholder types such as <code class="highlight"><c- k>auto</c-><c- o>&amp;</c-></code> to express these return
types, with the single exception of C++20’s <code class="highlight"><c- k>operator</c-><c- o>&lt;=></c-></code>. This leads to redundant repetition,
such as in this real code from libc++'s test suite:</p>
   <table>
    <tbody>
     <tr>
      <th>Today
      <th>After P2952
     <tr>
      <td> <small><pre class="highlight">
<c- k>struct</c-> <c- nc>ForwardDiffView</c-> <c- p>{</c->
  <c- p>[...]</c->
  <c- n>ForwardDiffView</c-><c- p>(</c-><c- n>ForwardDiffView</c-><c- o>&amp;&amp;</c-><c- p>)</c-> <c- o>=</c-> <c- k>default</c-><c- p>;</c->
  <c- n>ForwardDiffView</c-><c- p>(</c-><c- k>const</c-> <c- n>ForwardDiffView</c-><c- o>&amp;</c-><c- p>)</c-> <c- o>=</c-> <c- k>default</c-><c- p>;</c->
  <c- n>ForwardDiffView</c-><c- o>&amp;</c-> <c- k>operator</c-><c- o>=</c-><c- p>(</c-><c- n>ForwardDiffView</c-><c- o>&amp;&amp;</c-><c- p>)</c-> <c- o>=</c-> <c- k>default</c-><c- p>;</c->
  <c- n>ForwardDiffView</c-><c- o>&amp;</c-> <c- k>operator</c-><c- o>=</c-><c- p>(</c-><c- k>const</c-> <c- n>ForwardDiffView</c-><c- o>&amp;</c-><c- p>)</c-> <c- o>=</c-> <c- k>default</c-><c- p>;</c->
  <c- p>[...]</c->
<c- p>};</c->
</pre></small> 
      <td> <small><pre class="highlight">
<c- k>struct</c-> <c- nc>ForwardDiffView</c-> <c- p>{</c->
  <c- p>[...]</c->
  <c- n>ForwardDiffView</c-><c- p>(</c-><c- n>ForwardDiffView</c-><c- o>&amp;&amp;</c-><c- p>)</c-> <c- o>=</c-> <c- k>default</c-><c- p>;</c->
  <c- n>ForwardDiffView</c-><c- p>(</c-><c- k>const</c-> <c- n>ForwardDiffView</c-><c- o>&amp;</c-><c- p>)</c-> <c- o>=</c-> <c- k>default</c-><c- p>;</c->
  <c- k>auto</c-><c- o>&amp;</c-> <c- k>operator</c-><c- o>=</c-><c- p>(</c-><c- n>ForwardDiffView</c-><c- o>&amp;&amp;</c-><c- p>)</c-> <c- o>=</c-> <c- k>default</c-><c- p>;</c->
  <c- k>auto</c-><c- o>&amp;</c-> <c- k>operator</c-><c- o>=</c-><c- p>(</c-><c- k>const</c-> <c- n>ForwardDiffView</c-><c- o>&amp;</c-><c- p>)</c-> <c- o>=</c-> <c- k>default</c-><c- p>;</c->
  <c- p>[...]</c->
<c- p>};</c->
</pre></small> 
   </table>
   <p>The comparison operators are inconsistent among themselves: <code class="highlight"><c- k>operator</c-><c- o>&lt;=></c-></code> can deduce <code class="highlight"><c- n>strong_ordering</c-></code>, but the others cannot deduce <code class="highlight"><c- b>bool</c-></code>.</p>
   <table>
    <tbody>
     <tr>
      <th>Today
      <th>After P2952
     <tr>
      <td> <small><pre class="highlight">
<c- k>auto</c-> <c- k>operator</c-><c- o>&lt;=></c-><c- p>(</c-><c- k>const</c-> <c- n>MyClass</c-><c- o>&amp;</c-> <c- n>rhs</c-><c- p>)</c-> <c- k>const</c-> <c- o>=</c-> <c- k>default</c-><c- p>;</c->
<c- b>bool</c-> <c- k>operator</c-><c- o>==</c-><c- p>(</c-><c- k>const</c-> <c- n>MyClass</c-><c- o>&amp;</c-> <c- n>rhs</c-><c- p>)</c-> <c- k>const</c-> <c- o>=</c-> <c- k>default</c-><c- p>;</c->
<c- b>bool</c-> <c- k>operator</c-><c- o>&lt;</c-><c- p>(</c-><c- k>const</c-> <c- n>MyClass</c-><c- o>&amp;</c-> <c- n>rhs</c-><c- p>)</c-> <c- k>const</c-> <c- o>=</c-> <c- k>default</c-><c- p>;</c->
</pre></small> 
      <td> <small><pre class="highlight">
<c- k>auto</c-> <c- k>operator</c-><c- o>&lt;=></c-><c- p>(</c-><c- k>const</c-> <c- n>MyClass</c-><c- o>&amp;</c-> <c- n>rhs</c-><c- p>)</c-> <c- k>const</c-> <c- o>=</c-> <c- k>default</c-><c- p>;</c->
<c- k>auto</c-> <c- k>operator</c-><c- o>==</c-><c- p>(</c-><c- k>const</c-> <c- n>MyClass</c-><c- o>&amp;</c-> <c- n>rhs</c-><c- p>)</c-> <c- k>const</c-> <c- o>=</c-> <c- k>default</c-><c- p>;</c->
<c- k>auto</c-> <c- k>operator</c-><c- o>&lt;</c-><c- p>(</c-><c- k>const</c-> <c- n>MyClass</c-><c- o>&amp;</c-> <c- n>rhs</c-><c- p>)</c-> <c- k>const</c-> <c- o>=</c-> <c- k>default</c-><c- p>;</c->
</pre></small> 
   </table>
   <p>The status quo is inconsistent between non-defaulted and defaulted functions,
making it unnecessarily tedious to upgrade to <code class="highlight"><c- o>=</c-><c- k>default</c-></code>:</p>
   <table>
    <tbody>
     <tr>
      <th>Today
      <th>After P2952
     <tr>
      <td>
<pre class="highlight"><small><del><c- k>auto</c-></del><c- o>&amp;</c-> <c- k>operator</c-><c- o>=</c-><c- p>(</c-><c- k>const</c-> <c- n>MyClass</c-><c- o>&amp;</c-> <c- n>r</c-><c- p>)</c-> <del><c- p>{</c-> <c- n>i</c-> <c- o>=</c-> <c- n>r</c-><c- p>.</c-><c- n>i</c-><c- p>;</c-> <c- k>return</c-> <c- o>*</c-><c- k>this</c-><c- p>;</c-> <c- p>}</c-></del>
<ins><c- n>MyClass</c-></ins><c- o>&amp;</c-> <c- k>operator</c-><c- o>=</c-><c- p>(</c-><c- k>const</c-> <c- n>MyClass</c-><c- o>&amp;</c-> <c- n>r</c-><c- p>)</c-> <ins><c- o>=</c-> <c- k>default</c-><c- p>;</c-></ins>
</small></pre>
      <td>
<pre class="highlight"><small><c- k>auto</c-><c- o>&amp;</c-> <c- k>operator</c-><c- o>=</c-><c- p>(</c-><c- k>const</c-> <c- n>MyClass</c-><c- o>&amp;</c-> <c- n>r</c-><c- p>)</c-> <del><c- p>{</c-> <c- n>i</c-> <c- o>=</c-> <c- n>r</c-><c- p>.</c-><c- n>i</c-><c- p>;</c-> <c- k>return</c-> <c- o>*</c-><c- k>this</c-><c- p>;</c-> <c- p>}</c-></del>
<c- k>auto</c-><c- o>&amp;</c-> <c- k>operator</c-><c- o>=</c-><c- p>(</c-><c- k>const</c-> <c- n>MyClass</c-><c- o>&amp;</c-> <c- n>r</c-><c- p>)</c-> <ins><c- o>=</c-> <c- k>default</c-><c- p>;</c-></ins>
</small></pre>
     <tr>
      <td>
<pre class="highlight"><small><del><c- k>auto</c-></del> <c- k>operator</c-><c- o>==</c-><c- p>(</c-><c- k>const</c-> <c- n>MyClass</c-><c- o>&amp;</c-> <c- n>r</c-><c- p>)</c-> <c- k>const</c-> <del><c- p>{</c-> <c- k>return</c-> <c- n>i</c-> <c- o>==</c-> <c- n>r</c-><c- p>.</c-><c- n>i</c-><c- p>;</c-> <c- p>}</c-></del>
<ins><c- b>bool</c-></ins> <c- k>operator</c-><c- o>==</c-><c- p>(</c-><c- k>const</c-> <c- n>MyClass</c-><c- o>&amp;</c-> <c- n>r</c-><c- p>)</c-> <c- k>const</c-> <ins><c- o>=</c-> <c- k>default</c-><c- p>;</c-></ins>
</small></pre>
      <td>
<pre class="highlight"><small><c- k>auto</c-> <c- k>operator</c-><c- o>==</c-><c- p>(</c-><c- k>const</c-> <c- n>MyClass</c-><c- o>&amp;</c-> <c- n>r</c-><c- p>)</c-> <c- k>const</c-> <del><c- p>{</c-> <c- k>return</c-> <c- n>i</c-> <c- o>==</c-> <c- n>r</c-><c- p>.</c-><c- n>i</c-><c- p>;</c-> <c- p>}</c-></del>
<c- k>auto</c-> <c- k>operator</c-><c- o>==</c-><c- p>(</c-><c- k>const</c-> <c- n>MyClass</c-><c- o>&amp;</c-> <c- n>r</c-><c- p>)</c-> <c- k>const</c-> <ins><c- o>=</c-> <c- k>default</c-><c- p>;</c-></ins>
</small></pre>
   </table>
   <p>The ill-formedness of these declarations comes from overly restrictive wording in the standard,
such as <a href="https://eel.is/c++draft/class.eq#1.sentence-1">[class.eq]/1</a> specifically requiring that a defaulted equality
operator must have a <em>declared</em> return type of <code class="highlight"><c- b>bool</c-></code>, instead of simply specifying that its return type
must <em>be</em> <code class="highlight"><c- b>bool</c-></code>.
We believe each of the examples above has an intuitively clear meaning: the placeholder return type
correctly matches the type which the defaulted body will actually return. We propose to loosen the
current restrictions and permit these declarations to be well-formed.</p>
   <p>This proposal does not seek to change the set of valid return types for these functions.
We propose a purely syntactic change to expand the range of allowed declaration <em>syntax</em>, not semantics.
(But we do one drive-by clarification which we believe matches EWG’s original intent:
if an empty class’s defaulted <code class="highlight"><c- k>operator</c-><c- o>&lt;=></c-></code> returns a non-comparison-category type,
it should be defaulted as deleted.)</p>
   <h2 class="heading settled" data-level="3" id="proposal"><span class="secno">3. </span><span class="content">Proposal</span><a class="self-link" href="#proposal"></a></h2>
   <p>We propose that a defaulted function declaration with a placeholder return type should have its
type deduced (<a href="https://eel.is/c++draft/dcl.spec.auto.general#3.sentence-4">[dcl.spec.auto.general]</a>)
as if from a fictional return statement that returns:</p>
   <ul>
    <li data-md>
     <p>a prvalue of type <code class="highlight"><c- b>bool</c-></code>, in the case of <code class="highlight"><c- k>operator</c-><c- o>==</c-></code>, <code class="highlight"><c- k>operator</c-><c- o>!=</c-></code>, <code class="highlight"><c- k>operator</c-><c- o>&lt;</c-></code>, <code class="highlight"><c- k>operator</c-><c- o>></c-></code>, <code class="highlight"><c- k>operator</c-><c- o>&lt;=</c-></code>, or <code class="highlight"><c- k>operator</c-><c- o>>=</c-></code></p>
    <li data-md>
     <p>a prvalue of type <code class="highlight"><c- n>Q</c-></code>, in the case of <code class="highlight"><c- k>operator</c-><c- o>&lt;=></c-></code>; where <code class="highlight"><c- n>Q</c-></code> is the common comparison type of <i>R</i><sub>0</sub>, <i>R</i><sub>1</sub>,... <i>R</i><sub>n-1</sub></p>
    <li data-md>
     <p>an lvalue of type <code class="highlight"><c- n>C</c-></code>, in the case of <code class="highlight"><c- k>operator</c-><c- o>=</c-></code> for a class or union type <code class="highlight"><c- n>C</c-></code></p>
   </ul>
   <p>Then, the deduced return type is compared to the return type(s) permitted by the standard.
If the types match, the declaration is well-formed. Otherwise it’s ill-formed.</p>
   <div class="example" id="example-fd12758d">
    <a class="self-link" href="#example-fd12758d"></a> For the copy-assignment operator, our proposal gives the following behavior: 
<pre class="language-cpp highlight"><c- k>struct</c-> <c- nc>MyClass</c-> <c- p>{</c->
  <c- k>auto</c-><c- o>&amp;</c-> <c- k>operator</c-><c- o>=</c-><c- p>(</c-><c- k>const</c-> <c- n>MyClass</c-><c- o>&amp;</c-><c- p>)</c-> <c- o>=</c-> <c- k>default</c-><c- p>;</c->          <c- c1>// Proposed OK: deduces MyClass&amp;</c->
  <c- k>decltype</c-><c- p>(</c-><c- k>auto</c-><c- p>)</c-> <c- k>operator</c-><c- o>=</c-><c- p>(</c-><c- k>const</c-> <c- n>MyClass</c-><c- o>&amp;</c-><c- p>)</c-> <c- o>=</c-> <c- k>default</c-><c- p>;</c-> <c- c1>// Proposed OK: deduces MyClass&amp;</c->
  <c- k>auto</c-><c- o>&amp;&amp;</c-> <c- k>operator</c-><c- o>=</c-><c- p>(</c-><c- k>const</c-> <c- n>MyClass</c-><c- o>&amp;</c-><c- p>)</c-> <c- o>=</c-> <c- k>default</c-><c- p>;</c->         <c- c1>// Proposed OK: deduces MyClass&amp;</c->
  <c- k>const</c-> <c- k>auto</c-><c- o>&amp;</c-> <c- k>operator</c-><c- o>=</c-><c- p>(</c-><c- k>const</c-> <c- n>MyClass</c-><c- o>&amp;</c-><c- p>)</c-> <c- o>=</c-> <c- k>default</c-><c- p>;</c->    <c- c1>// Still ill-formed: deduced const MyClass&amp; is not MyClass&amp;</c->
  <c- k>auto</c-> <c- k>operator</c-><c- o>=</c-><c- p>(</c-><c- k>const</c-> <c- n>MyClass</c-><c- o>&amp;</c-><c- p>)</c-> <c- o>=</c-> <c- k>default</c-><c- p>;</c->           <c- c1>// Still ill-formed: deduced MyClass is not MyClass&amp;</c->
  <c- k>auto</c-><c- o>*</c-> <c- k>operator</c-><c- o>=</c-><c- p>(</c-><c- k>const</c-> <c- n>MyClass</c-><c- o>&amp;</c-><c- p>)</c-> <c- o>=</c-> <c- k>default</c-><c- p>;</c->          <c- c1>// Still ill-formed: deduction fails</c->
  <c- b>void</c-> <c- k>operator</c-><c- o>=</c-><c- p>(</c-><c- k>const</c-> <c- n>MyClass</c-><c- o>&amp;</c-><c- p>)</c-> <c- o>=</c-> <c- k>default</c-><c- p>;</c->           <c- c1>// Still ill-formed: void is not MyClass&amp;</c->
<c- p>};</c->
</pre>
    <p>For <code class="highlight"><c- k>operator</c-><c- o>==</c-></code>, our proposal gives the following behavior:</p>
<pre class="language-cpp highlight"><c- k>struct</c-> <c- nc>MyClass</c-> <c- p>{</c->
  <c- k>auto</c-> <c- k>operator</c-><c- o>==</c-><c- p>(</c-><c- k>const</c-> <c- n>MyClass</c-><c- o>&amp;</c-><c- p>)</c-> <c- k>const</c-> <c- o>=</c-> <c- k>default</c-><c- p>;</c->           <c- c1>// Proposed OK: deduces bool</c->
  <c- k>decltype</c-><c- p>(</c-><c- k>auto</c-><c- p>)</c-> <c- k>operator</c-><c- o>==</c-><c- p>(</c-><c- k>const</c-> <c- n>MyClass</c-><c- o>&amp;</c-><c- p>)</c-> <c- k>const</c-> <c- o>=</c-> <c- k>default</c-><c- p>;</c-> <c- c1>// Proposed OK: deduces bool</c->
  <c- k>auto</c-><c- o>&amp;&amp;</c-> <c- k>operator</c-><c- o>==</c-><c- p>(</c-><c- k>const</c-> <c- n>MyClass</c-><c- o>&amp;</c-><c- p>)</c-> <c- k>const</c-> <c- o>=</c-> <c- k>default</c-><c- p>;</c->         <c- c1>// Still ill-formed: deduced bool&amp;&amp; is not bool</c->
  <c- k>auto</c-><c- o>&amp;</c-> <c- k>operator</c-><c- o>==</c-><c- p>(</c-><c- k>const</c-> <c- n>MyClass</c-><c- o>&amp;</c-><c- p>)</c-> <c- k>const</c-> <c- o>=</c-> <c- k>default</c-><c- p>;</c->          <c- c1>// Still ill-formed: deduction fails</c->
<c- p>};</c->
</pre>
   </div>
   <h3 class="heading settled" data-level="3.1" id="declared-type"><span class="secno">3.1. </span><span class="content">"Return type" versus "declared return type"</span><a class="self-link" href="#declared-type"></a></h3>
   <p>Today, vendors unanimously reject <code class="highlight"><c- k>auto</c-><c- o>&amp;</c-> <c- k>operator</c-><c- o>=</c-><c- p>(</c-><c- k>const</c-> <c- n>A</c-><c- o>&amp;</c-><c- p>)</c-> <c- o>=</c-> <c- k>default</c-></code>.
But we can’t find any wording in <a href="https://eel.is/c++draft/class.copy.assign">[class.copy.assign]</a> or <a href="https://eel.is/c++draft/dcl.fct.def.default">[dcl.fct.def.default]</a> that directly justifies
this behavior. It seems that vendors are interpreting e.g. <a href="https://eel.is/c++draft/dcl.fct.def.default#2.5">[dcl.fct.def.default]/2.5</a>’s
"[if] the return type of F<sub>1</sub> differs from the return type of F<sub>2</sub>"
to mean "the <em>declared</em> return type of F<sub>1</sub>," even though newer sections such as <a href="https://eel.is/c++draft/class.compare">[class.compare]</a> consistently distinguish
the "declared return type" from the (actual) return type.</p>
   <p>We tentatively propose to leave <a href="https://eel.is/c++draft/dcl.fct.def.default">[dcl.fct.def.default]</a> alone,
and simply add an example that indicates the (new) intent of the (existing) wording: that it should
now be interpreted as talking about the assignment operator’s <em>actual</em> return type,
not its <em>declared</em> (placeholder) return type.</p>
   <h3 class="heading settled" data-level="3.2" id="defaulted-as-deleted"><span class="secno">3.2. </span><span class="content">"Defaulted as deleted"</span><a class="self-link" href="#defaulted-as-deleted"></a></h3>
   <p>The current wording for comparison operators is crafted so that the following <code class="highlight"><c- n>Container</c-></code> is well-formed.
Its <code class="highlight"><c- k>operator</c-><c- o>&lt;=></c-></code> is defaulted as deleted (so that operator is unusable), but the instantiation
of class <code class="highlight"><c- n>Container</c-><c- o>&lt;</c-><c- n>mutex</c-><c- o>></c-></code> itself is OK. We need to preserve this in our rewriting.
(<a href="https://godbolt.org/z/jcPf1Ge9W">Godbolt.</a>)</p>
<pre class="language-cpp highlight"><c- k>template</c-><c- o>&lt;</c-><c- k>class</c-> <c- nc>T</c-><c- o>></c->
<c- k>struct</c-> <c- nc>Container</c-> <c- p>{</c->
  <c- n>T</c-> <c- n>t</c-><c- p>;</c->
  <c- k>auto</c-> <c- k>operator</c-><c- o>&lt;=></c-><c- p>(</c-><c- k>const</c-> <c- n>Container</c-><c- o>&amp;</c-><c- p>)</c-> <c- k>const</c-> <c- o>=</c-> <c- k>default</c-><c- p>;</c->
<c- p>};</c->

<c- n>Container</c-><c- o>&lt;</c-><c- n>std</c-><c- o>::</c-><c- n>mutex</c-><c- o>></c-> <c- n>cm</c-><c- p>;</c->
  <c- c1>// OK, &lt;=> is deleted</c->

<c- k>struct</c-> <c- nc>Weird</c-> <c- p>{</c-> <c- b>int</c-> <c- k>operator</c-><c- o>&lt;=></c-><c- p>(</c-><c- n>Weird</c-><c- p>)</c-> <c- k>const</c-><c- p>;</c-> <c- p>};</c->
<c- n>Container</c-><c- o>&lt;</c-><c- n>Weird</c-><c- o>></c-> <c- n>cw</c-><c- p>;</c->
  <c- c1>// OK, &lt;=> is deleted because Weird's operator&lt;=></c->
  <c- c1>// returns a non-comparison-category type</c->
</pre>
   <p>Similarly for dependent return types:</p>
<pre class="language-cpp highlight"><c- k>template</c-><c- o>&lt;</c-><c- k>class</c-> <c- nc>R</c-><c- o>></c->
<c- k>struct</c-> <c- nc>C</c-> <c- p>{</c->
  <c- b>int</c-> <c- n>i</c-><c- p>;</c->
  <c- n>R</c-> <c- k>operator</c-><c- o>&lt;=></c-><c- p>(</c-><c- k>const</c-> <c- n>C</c-><c- o>&amp;</c-><c- p>)</c-> <c- k>const</c-> <c- o>=</c-> <c- k>default</c-><c- p>;</c->
<c- p>};</c->
<c- k>static_assert</c-><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- n>three_way_comparable</c-><c- o>&lt;</c-><c- n>C</c-><c- o>&lt;</c-><c- n>std</c-><c- o>::</c-><c- n>strong_ordering</c-><c- o>>></c-><c- p>);</c->
<c- k>static_assert</c-><c- p>(</c-><c- o>!</c-><c- n>std</c-><c- o>::</c-><c- n>three_way_comparable</c-><c- o>&lt;</c-><c- n>C</c-><c- o>&lt;</c-><c- b>int</c-><c- o>>></c-><c- p>);</c->
  <c- c1>// OK, C&lt;int>'s operator&lt;=> is deleted</c->
</pre>
   <p>Therefore we can’t just say "<code class="highlight"><c- k>operator</c-><c- o>&lt;=></c-></code> <em>shall</em> have a return type which is a comparison category type";
we must say that if the return type is not a comparison category type then the operator is defaulted as deleted.</p>
   <h3 class="heading settled" data-level="3.3" id="deducing-this"><span class="secno">3.3. </span><span class="content">"Deducing <code class="highlight"><c- k>this</c-></code>" and CWG2586</span><a class="self-link" href="#deducing-this"></a></h3>
   <p><a data-link-type="biblio" href="#biblio-cwg2586" title="Explicit object parameter for assignment and comparison">[CWG2586]</a> (adopted for C++23) permits defaulted functions to have explicit object parameters.
This constrains the wordings we can choose for <code class="highlight"><c- k>operator</c-><c- o>=</c-></code>: we can’t say “the return type is deduced
as if from <code class="highlight"><c- k>return</c-> <c- o>*</c-><c- k>this</c-></code>” because there might not be a <code class="highlight"><c- o>*</c-><c- k>this</c-></code>.</p>
   <p>There’s a quirk with rvalue-ref-qualified assignment operators — not <em>move</em> assignment, but
assignment where the <em>destination</em> object is explicitly rvalue-ref-qualified.</p>
   <ul>
    <li data-md>
     <p><code class="highlight"><c- k>auto</c-><c- o>&amp;&amp;</c-> <c- k>operator</c-><c- o>=</c-><c- p>(</c-><c- k>const</c-> <c- n>B</c-><c- o>&amp;</c-><c- p>)</c-> <c- o>&amp;&amp;</c-> <c- p>{</c-> <c- k>return</c-> <c- o>*</c-><c- k>this</c-><c- p>;</c-> <c- p>}</c-></code> deduces an lvalue reference</p>
    <li data-md>
     <p><code class="highlight"><c- k>auto</c-><c- o>&amp;&amp;</c-> <c- k>operator</c-><c- o>=</c-><c- p>(</c-><c- k>this</c-> <c- n>B</c-><c- o>&amp;&amp;</c-> <c- n>self</c-><c- p>,</c-> <c- k>const</c-> <c- n>B</c-><c- o>&amp;</c-><c- p>)</c-> <c- p>{</c-> <c- k>return</c-> <c- n>self</c-><c- p>;</c-> <c- p>}</c-></code> deduces an rvalue reference</p>
   </ul>
   <p>Nonetheless, a <em>defaulted</em> assignment operator always returns an lvalue reference
(<a href="https://eel.is/c++draft/class.copy.assign#6.sentence-1">[class.copy.assign]/6</a>, <a href="https://eel.is/c++draft/dcl.fct.def.default#2.5">[dcl.fct.def.default]/2.5</a>),
regardless of whether it’s declared using explicit object syntax.</p>
<pre class="language-cpp highlight"><c- k>struct</c-> <c- nc>A</c-> <c- p>{</c->
  <c- n>A</c-><c- o>&amp;</c-> <c- k>operator</c-><c- o>=</c-><c- p>(</c-><c- k>const</c-> <c- n>A</c-><c- o>&amp;</c-><c- p>)</c-> <c- o>&amp;&amp;</c-> <c- o>=</c-> <c- k>default</c-><c- p>;</c-> <c- c1>// OK today</c->
  <c- n>A</c-><c- o>&amp;&amp;</c-> <c- k>operator</c-><c- o>=</c-><c- p>(</c-><c- k>const</c-> <c- n>A</c-><c- o>&amp;</c-><c- p>)</c-> <c- o>&amp;&amp;</c-> <c- o>=</c-> <c- k>default</c-><c- p>;</c-> <c- c1>// Ill-formed, return type isn't A&amp;</c->
  <c- k>decltype</c-><c- p>(</c-><c- k>auto</c-><c- p>)</c-> <c- k>operator</c-><c- o>=</c-><c- p>(</c-><c- k>const</c-> <c- n>A</c-><c- o>&amp;</c-><c- p>)</c-> <c- o>&amp;&amp;</c-> <c- p>{</c-> <c- k>return</c-> <c- o>*</c-><c- k>this</c-><c- p>;</c-> <c- p>}</c-> <c- c1>// OK, deduces A&amp;</c->
  <c- k>decltype</c-><c- p>(</c-><c- k>auto</c-><c- p>)</c-> <c- k>operator</c-><c- o>=</c-><c- p>(</c-><c- k>const</c-> <c- n>A</c-><c- o>&amp;</c-><c- p>)</c-> <c- o>&amp;&amp;</c-> <c- o>=</c-> <c- k>default</c-><c- p>;</c-> <c- c1>// Proposed OK, deduces A&amp;</c->
<c- p>};</c->
<c- k>struct</c-> <c- nc>B</c-> <c- p>{</c->
  <c- n>B</c-><c- o>&amp;</c-> <c- k>operator</c-><c- o>=</c-><c- p>(</c-><c- k>this</c-> <c- n>B</c-><c- o>&amp;&amp;</c-> <c- n>self</c-><c- p>,</c-> <c- k>const</c-> <c- n>B</c-><c- o>&amp;</c-><c- p>)</c-> <c- p>{</c-> <c- k>return</c-> <c- n>self</c-><c- p>;</c-> <c- p>}</c-> <c- c1>// Error, self can't bind to B&amp;</c->
  <c- n>B</c-><c- o>&amp;&amp;</c-> <c- k>operator</c-><c- o>=</c-><c- p>(</c-><c- k>this</c-> <c- n>B</c-><c- o>&amp;&amp;</c-> <c- n>self</c-><c- p>,</c-> <c- k>const</c-> <c- n>B</c-><c- o>&amp;</c-><c- p>)</c-> <c- p>{</c-> <c- k>return</c-> <c- n>self</c-><c- p>;</c-> <c- p>}</c-> <c- c1>// OK</c->
  <c- k>decltype</c-><c- p>(</c-><c- k>auto</c-><c- p>)</c-> <c- k>operator</c-><c- o>=</c-><c- p>(</c-><c- k>this</c-> <c- n>B</c-><c- o>&amp;&amp;</c-> <c- n>self</c-><c- p>,</c-> <c- k>const</c-> <c- n>B</c-><c- o>&amp;</c-><c- p>)</c-> <c- p>{</c-> <c- k>return</c-> <c- n>self</c-><c- p>;</c-> <c- p>}</c-> <c- c1>// OK, deduces B&amp;&amp;</c->
  <c- n>B</c-><c- o>&amp;</c-> <c- k>operator</c-><c- o>=</c-><c- p>(</c-><c- k>this</c-> <c- n>B</c-><c- o>&amp;</c-> <c- n>self</c-><c- p>,</c-> <c- k>const</c-> <c- n>B</c-><c- o>&amp;</c-><c- p>)</c-> <c- o>=</c-> <c- k>default</c-><c- p>;</c-> <c- c1>// OK</c->
  <c- n>B</c-><c- o>&amp;</c-> <c- k>operator</c-><c- o>=</c-><c- p>(</c-><c- k>this</c-> <c- n>B</c-><c- o>&amp;&amp;</c-> <c- n>self</c-><c- p>,</c-> <c- k>const</c-> <c- n>B</c-><c- o>&amp;</c-><c- p>)</c-> <c- o>=</c-> <c- k>default</c-><c- p>;</c-> <c- c1>// OK</c->
  <c- n>B</c-><c- o>&amp;&amp;</c-> <c- k>operator</c-><c- o>=</c-><c- p>(</c-><c- k>this</c-> <c- n>B</c-><c- o>&amp;&amp;</c-> <c- n>self</c-><c- p>,</c-> <c- k>const</c-> <c- n>B</c-><c- o>&amp;</c-><c- p>)</c-> <c- o>=</c-> <c- k>default</c-><c- p>;</c-> <c- c1>// Ill-formed, return type isn't B&amp;</c->
  <c- k>decltype</c-><c- p>(</c-><c- k>auto</c-><c- p>)</c-> <c- k>operator</c-><c- o>=</c-><c- p>(</c-><c- k>this</c-> <c- n>B</c-><c- o>&amp;&amp;</c-> <c- n>self</c-><c- p>,</c-> <c- k>const</c-> <c- n>B</c-><c- o>&amp;</c-><c- p>)</c-> <c- o>=</c-> <c- k>default</c-><c- p>;</c-> <c- c1>// Proposed OK, deduces B&amp;</c->
<c- p>};</c->
</pre>
   <p>Defaulted rvalue-ref-qualified assignment operators are weird; Arthur is bringing another paper
to forbid them entirely (<a data-link-type="biblio" href="#biblio-p2953" title="Forbid defaulting operator=(X&amp;&amp;) &amp;&amp;">[P2953]</a>). However, P2952 doesn’t need to treat them specially.
Defaulted assignment operators invariably return lvalue references, so we invariably deduce as-if-from
an lvalue reference, full stop.</p>
   <p>See <a href="#polls">§ 5 Straw poll results</a>.</p>
   <h3 class="heading settled" data-level="3.4" id="new-burden"><span class="secno">3.4. </span><span class="content">Burden on specifying new defaultable operators</span><a class="self-link" href="#new-burden"></a></h3>
   <p>We propose to leave <a href="https://eel.is/c++draft/dcl.fct.def.default">[dcl.fct.def.default]</a> alone
and reinterpret its term "return type" to mean the actual return type, not the declared return type.
This will, by default, permit the programmer to use placeholder return types on their defaulted operators.
So there is a new burden on the specification of the defaultable operator, to specify exactly how
return type deduction works for the implicitly defined operator.</p>
   <div class="example" id="example-09bb643e">
    <a class="self-link" href="#example-09bb643e"></a> <a data-link-type="biblio" href="#biblio-p1046r2" title="Automatically Generate More Operators">[P1046R2]</a> proposed to make <code class="highlight"><c- k>operator</c-><c- o>++</c-><c- p>(</c-><c- b>int</c-><c- p>)</c-></code> defaultable in the same way as a
secondary comparison operator. It would presumably have done this by
adding wording to <a href="https://eel.is/c++draft/over.oper#over.inc">[over.inc]</a>. After P2952, this
added wording would need to include a sentence like: 
    <p><small></small></p>
    <blockquote><small> A defaulted postfix <code class="highlight"><c- k>operator</c-><c- o>++</c-></code> for class <code class="highlight"><c- n>X</c-></code> shall have a return type that is <code class="highlight"><c- n>X</c-></code> or <code class="highlight"><c- b>void</c-></code>.
If its declared return type contains a placeholder type, its return type is deduced as if from<p></p> <ul><li data-md><p><code class="highlight"><c- k>return</c-> <c- n>X</c-><c- p>(</c-><c- n>r</c-><c- p>);</c-></code> where <code class="highlight"><c- n>r</c-></code> is an lvalue reference to the function’s object parameter, if <code class="highlight"><c- n>X</c-><c- p>(</c-><c- n>r</c-><c- p>)</c-></code> is a well-formed expression;</p> </li><li data-md><p><code class="highlight"><c- k>return</c-><c- p>;</c-></code> otherwise.</p> </li></ul> </small></blockquote>
    <p><a data-link-type="biblio" href="#biblio-p0847" title="Deducing this">[P0847]</a> <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p0847r7.html#crtp">§5.2</a>’s
example of <code class="highlight"><c- n>add_postfix_increment</c-></code> ("CRTP without the C, R, or even T") involves an <code class="highlight"><c- k>operator</c-><c- o>++</c-></code> with return
type <code class="highlight"><c- k>auto</c-></code>; but that <code class="highlight"><c- k>operator</c-><c- o>++</c-></code> is not defaulted, and probably couldn’t be defaulted even after <a data-link-type="biblio" href="#biblio-p1046r2" title="Automatically Generate More Operators">[P1046R2]</a>, firstly
because it is a template and secondly because its deduced return type is <code class="highlight"><c- n>Self</c-></code> instead of <code class="highlight"><c- n>add_postfix_increment</c-></code>.</p>
<pre class="language-cpp highlight"><c- k>struct</c-> <c- nc>add_postfix_increment</c-> <c- p>{</c->
    <c- k>template</c-><c- o>&lt;</c-><c- k>class</c-> <c- nc>Self</c-><c- o>></c->
    <c- k>auto</c-> <c- k>operator</c-><c- o>++</c-><c- p>(</c-><c- k>this</c-> <c- n>Self</c-><c- o>&amp;</c-><c- p>,</c-> <c- b>int</c-><c- p>)</c-> <c- o>=</c-> <c- k>default</c-><c- p>;</c->
      <c- c1>// Today: ill-formed, can't default operator++</c->
      <c- c1>// After P1046R2: presumably still not OK, can't default a template</c->
<c- p>};</c->
<c- k>struct</c-> <c- nc>S</c-> <c- o>:</c-> <c- n>add_postfix_increment</c-> <c- p>{</c->
    <c- b>int</c-> <c- n>i</c-><c- p>;</c->
    <c- k>auto</c-><c- o>&amp;</c-> <c- k>operator</c-><c- o>++</c-><c- p>()</c-> <c- p>{</c-> <c- o>++</c-><c- n>i</c-><c- p>;</c-> <c- k>return</c-> <c- o>*</c-><c- k>this</c-><c- p>;</c-> <c- p>}</c->
    <c- k>using</c-> <c- n>add_postfix_increment</c-><c- o>::</c-><c- k>operator</c-><c- o>++</c-><c- p>;</c->
<c- p>};</c->
<c- n>S</c-> <c- n>s</c-> <c- o>=</c-> <c- p>{</c-><c- mi>1</c-><c- p>};</c->
<c- n>S</c-> <c- n>t</c-> <c- o>=</c-> <c- n>s</c-><c- o>++</c-><c- p>;</c->
</pre>
   </div>
   <h3 class="heading settled" data-level="3.5" id="other-return-types"><span class="secno">3.5. </span><span class="content">Other return types are still forbidden</span><a class="self-link" href="#other-return-types"></a></h3>
   <p>Notice that returning any type other than <code class="highlight"><c- n>X</c-><c- o>&amp;</c-></code> from a defaulted <code class="highlight"><c- n>X</c-><c- o>::</c-><c- k>operator</c-><c- o>=</c-></code> remains ill-formed.
For example, we don’t propose to accept:</p>
<pre class="language-cpp highlight"><c- k>struct</c-> <c- nc>X</c-> <c- p>{</c->
  <c- b>void</c-> <c- k>operator</c-><c- o>=</c-><c- p>(</c-><c- n>X</c-><c- o>&amp;&amp;</c-><c- p>)</c-> <c- o>=</c-> <c- k>default</c-><c- p>;</c-> <c- c1>// still ill-formed</c->
<c- p>};</c->
</pre>
   <p>Any paper that did propose to permit defaulting <code class="highlight"><c- b>void</c-> <c- k>operator</c-><c- o>=</c-></code> would have to consider very carefully
whether to call that operator "trivial." Today, <code class="highlight"><c- n>is_trivially_move_assignable_v</c-><c- o>&lt;</c-><c- n>T</c-><c- o>></c-></code> is true only when <code class="highlight"><c- k>decltype</c-><c- p>(</c-><c- n>declval</c-><c- o>&lt;</c-><c- n>T</c-><c- o>&amp;></c-><c- p>()</c-> <c- o>=</c-> <c- n>declval</c-><c- o>&lt;</c-><c- n>T</c-><c- o>></c-><c- p>())</c-></code> is <code class="highlight"><c- n>T</c-><c- o>&amp;</c-></code>. It’s just barely conceivable that existing
user code <em>might</em> rely on that fact, and break when presented with a trivial assignment
operator that returned <code class="highlight"><c- b>void</c-></code> instead. And certainly the return-by-copy <code class="highlight"><c- n>X</c-> <c- k>operator</c-><c- o>=</c-><c- p>(</c-><c- n>X</c-><c- o>&amp;&amp;</c-><c- p>)</c-> <c- o>=</c-> <c- k>default</c-></code> shouldn’t be considered "trivial" for non-trivially-copy-constructible <code class="highlight"><c- n>X</c-></code>.</p>
   <p>But none of this is a problem for this proposal P2952, because we propose to continue rejecting
a defaulted <code class="highlight"><c- n>X</c-><c- o>::</c-><c- k>operator</c-><c- o>=</c-></code> that returns any type but <code class="highlight"><c- n>X</c-><c- o>&amp;</c-></code>. We merely propose to allow the programmer
to <em>spell</em> that return type using a placeholder such as <code class="highlight"><c- k>auto</c-><c- o>&amp;</c-></code>.</p>
   <h3 class="heading settled" data-level="3.6" id="corner-cases"><span class="secno">3.6. </span><span class="content">Existing corner cases</span><a class="self-link" href="#corner-cases"></a></h3>
   <p>There is vendor divergence in some corner cases. Here is a table of the divergences we found,
plus our opinion as to the conforming behavior, and our proposed behavior.</p>
   <p><small></small></p>
   <p></p>
   <table>
    <tbody>
     <tr>
      <th>URL
      <th>Code
      <th>Clang
      <th>GCC
      <th>MSVC
      <th>EDG
      <th>Correct
     <tr>
      <td><a href="https://godbolt.org/z/3EqYc43xh">link</a>
      <td>
<pre class="highlight"><c- k>const</c-> <c- b>bool</c-> <c- k>operator</c-><c- o>==</c-><c- p>(</c-><c- k>const</c-> <c- n>C</c-><c- o>&amp;</c-><c- p>)</c-> <c- k>const</c-> <c- o>=</c-> <c- k>default</c-><c- p>;</c-></pre>
      <td>✗
      <td>✗
      <td>✗
      <td bgcolor="#FFCACA">✓
      <td><a href="https://eel.is/c++draft/class.eq#1.sentence-1">✗</a>
     <tr>
      <td><a href="https://godbolt.org/z/hx9vvorsn">link</a>
      <td>
<pre class="highlight"><c- k>friend</c-> <c- b>bool</c-> <c- k>operator</c-><c- o>==</c-><c- p>(</c-><c- k>const</c-> <c- n>C</c-><c- p>,</c-> <c- k>const</c-> <c- n>C</c-><c- p>)</c-> <c- o>=</c-> <c- k>default</c-><c- p>;</c-></pre>
      <td>✓
      <td bgcolor="#FFCACA">✗
      <td>✓
      <td>✓
      <td><a href="https://eel.is/c++draft/class.compare#default-1.sentence-1">✓</a>
     <tr>
      <td><a href="https://godbolt.org/z/e7Eba49qr">link</a>
      <td>
<pre class="highlight"><c- k>decltype</c-><c- p>(</c-><c- k>auto</c-><c- p>)</c-> <c- k>operator</c-><c- o>&lt;=></c-><c- p>(</c-><c- k>const</c-> <c- n>C</c-><c- o>&amp;</c-><c- p>)</c-> <c- k>const</c-> <c- o>=</c-> <c- k>default</c-><c- p>;</c-></pre>
      <td>✗
      <td bgcolor="#FFCACA">✓
      <td>✗
      <td>✗
      <td>Today: <a href="https://eel.is/c++draft/class.compare#class.spaceship-2.2.sentence-1">✗</a><br>Proposed: ✓
     <tr>
      <td><a href="https://godbolt.org/z/heEs3haxs">link</a>
      <td>
<pre class="highlight"><c- k>const</c-> <c- k>auto</c-> <c- k>operator</c-><c- o>&lt;=></c-><c- p>(</c-><c- k>const</c-> <c- n>C</c-><c- o>&amp;</c-><c- p>)</c-> <c- k>const</c-> <c- o>=</c-> <c- k>default</c-><c- p>;</c-></pre>
      <td>✗
      <td>✗
      <td bgcolor="#FFCACA">✓
      <td bgcolor="#FFCACA">✓
      <td>Today: <a href="https://eel.is/c++draft/class.compare#class.spaceship-2.2.sentence-1">✗</a><br>Proposed: ✗
     <tr>
      <td><a href="https://godbolt.org/z/jcz8ceeKx">link</a>
      <td>
<pre class="highlight"><c- n>True</c-> <c- k>auto</c-> <c- k>operator</c-><c- o>&lt;=></c-><c- p>(</c-><c- k>const</c-> <c- n>C</c-><c- o>&amp;</c-><c- p>)</c-> <c- k>const</c-> <c- o>=</c-> <c- k>default</c-><c- p>;</c-></pre>
      <td>✗
      <td bgcolor="#FFCACA">✓
      <td bgcolor="#FFCACA">✓
      <td bgcolor="#FFCACA">✓
      <td>Today: <a href="https://eel.is/c++draft/class.compare#class.spaceship-2.2.sentence-1">✗</a><br>Proposed: ✓
     <tr>
      <td><a href="https://godbolt.org/z/Ps9sEzWsn">link</a>
      <td>
<pre class="highlight"><c- n>False</c-> <c- k>auto</c-> <c- k>operator</c-><c- o>&lt;=></c-><c- p>(</c-><c- k>const</c-> <c- n>C</c-><c- o>&amp;</c-><c- p>)</c-> <c- k>const</c-> <c- o>=</c-> <c- k>default</c-><c- p>;</c-></pre>
      <td>✗
      <td bgcolor="#FFCACA">unmet
      <td bgcolor="#FFCACA">✓
      <td bgcolor="#FFCACA">✓
      <td>Today: <a href="https://eel.is/c++draft/class.compare#class.spaceship-2.2.sentence-1">✗</a><br>Proposed: unmet
     <tr>
      <td><a href="https://godbolt.org/z/aPWEs5xnb">link</a>
      <td>
<pre class="highlight"><c- k>struct</c-> <c- nc>U</c-> <c- p>{</c-> <c- n>U</c-><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- n>strong_ordering</c-><c- p>);</c-> <c- p>};</c->
<c- k>struct</c-> <c- nc>C</c-> <c- p>{</c->
  <c- n>U</c-> <c- k>operator</c-><c- o>&lt;=></c-><c- p>(</c-><c- k>const</c-> <c- n>C</c-><c- o>&amp;</c-><c- p>)</c-> <c- k>const</c-> <c- o>=</c-> <c- k>default</c-><c- p>;</c->
<c- p>};</c-></pre>
      <td>✓
      <td>✓
      <td bgcolor="#FFCACA">✗
      <td bgcolor="#FFCACA">deleted
      <td>Today: ✓<br>Proposed: deleted
     <tr>
      <td><a href="https://godbolt.org/z/ePnnvvdsz">link</a>
      <td>
<pre class="highlight"><c- k>struct</c-> <c- nc>U</c-> <c- p>{</c-> <c- n>U</c-><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- n>strong_ordering</c-><c- p>);</c-> <c- k>operator</c-> <c- b>int</c-><c- p>();</c-> <c- p>};</c->
<c- k>struct</c-> <c- nc>C</c-> <c- p>{</c->
  <c- b>int</c-> <c- n>i</c-><c- p>;</c->
  <c- n>U</c-> <c- k>operator</c-><c- o>&lt;=></c-><c- p>(</c-><c- k>const</c-> <c- n>C</c-><c- o>&amp;</c-><c- p>)</c-> <c- k>const</c-> <c- o>=</c-> <c- k>default</c-><c- p>;</c->
<c- p>};</c-></pre>
      <td bgcolor="#FFCACA">✓
      <td bgcolor="#FFCACA">✓
      <td bgcolor="#FFCACA">✗
      <td>deleted
      <td><a href="https://eel.is/c++draft/class.compare#class.spaceship-2.2.sentence-2">deleted</a>
     <tr>
      <td><a href="https://godbolt.org/z/T6bnsMqWo">link</a>
      <td>
<pre class="highlight"><c- k>struct</c-> <c- nc>C</c-> <c- p>{</c->
  <c- b>int</c-> <c- n>i</c-><c- p>;</c->
  <c- k>const</c-> <c- n>std</c-><c- o>::</c-><c- n>strong_ordering</c-><c- o>&amp;</c->
    <c- k>operator</c-><c- o>&lt;=></c-><c- p>(</c-><c- k>const</c-> <c- n>C</c-><c- o>&amp;</c-><c- p>)</c-> <c- k>const</c-> <c- o>=</c-> <c- k>default</c-><c- p>;</c->
<c- p>};</c-></pre>
      <td bgcolor="#FFCACA">✓
      <td>deleted
      <td bgcolor="#FFCACA">✓
      <td>deleted
      <td>deleted
     <tr>
      <td><a href="https://godbolt.org/z/W3eW1Tdb9">link</a>
      <td>
<pre class="highlight"><c- k>struct</c-> <c- nc>C</c-> <c- p>{</c->
  <c- k>const</c-> <c- n>std</c-><c- o>::</c-><c- n>strong_ordering</c-><c- o>&amp;</c->
    <c- k>operator</c-><c- o>&lt;=></c-><c- p>(</c-><c- k>const</c-> <c- n>C</c-><c- o>&amp;</c-><c- p>)</c-> <c- k>const</c-> <c- o>=</c-> <c- k>default</c-><c- p>;</c->
<c- p>};</c-></pre>
      <td>✓
      <td>✓
      <td>✓
      <td bgcolor="#FFCACA">deleted
      <td>Today: ✓<br>Proposed: deleted
     <tr>
      <td><a href="https://godbolt.org/z/KTTGMjWox">link</a>
      <td>
<pre class="highlight"><c- k>struct</c-> <c- nc>W</c-> <c- p>{</c->
  <c- k>const</c-> <c- n>std</c-><c- o>::</c-><c- n>strong_ordering</c->
    <c- k>operator</c-><c- o>&lt;=></c-><c- p>(</c-><c- k>const</c-> <c- n>W</c-><c- o>&amp;</c-><c- p>)</c-> <c- k>const</c-><c- p>;</c->
<c- p>};</c->
<c- k>struct</c-> <c- nc>C</c-> <c- p>{</c->
  <c- n>W</c-> <c- n>w</c-><c- p>;</c->
  <c- k>auto</c-> <c- k>operator</c-><c- o>&lt;=></c-><c- p>(</c-><c- k>const</c-> <c- n>C</c-><c- o>&amp;</c-><c- p>)</c-> <c- k>const</c-> <c- o>=</c-> <c- k>default</c-><c- p>;</c->
<c- p>};</c-></pre>
      <td bgcolor="#FFCACA">✓
      <td bgcolor="#FFCACA">✗
      <td bgcolor="#FFCACA">✓
      <td>deleted
      <td><a href="https://eel.is/c++draft/class.compare#class.spaceship-2.1.sentence-2">deleted</a>
     <tr>
      <td><a href="https://godbolt.org/z/3T4b9YM6r">link</a>
      <td>
<pre class="highlight"><c- k>struct</c-> <c- nc>W</c-> <c- p>{</c->
  <c- k>const</c-> <c- n>std</c-><c- o>::</c-><c- n>strong_ordering</c->
    <c- k>operator</c-><c- o>&lt;=></c-><c- p>(</c-><c- k>const</c-> <c- n>W</c-><c- o>&amp;</c-><c- p>)</c-> <c- k>const</c-><c- p>;</c->
<c- p>};</c->
<c- k>struct</c-> <c- nc>C</c-> <c- p>{</c->
  <c- n>W</c-> <c- n>w</c-><c- p>;</c->
  <c- n>std</c-><c- o>::</c-><c- n>strong_ordering</c->
    <c- k>operator</c-><c- o>&lt;=></c-><c- p>(</c-><c- k>const</c-> <c- n>C</c-><c- o>&amp;</c-><c- p>)</c-> <c- k>const</c-> <c- o>=</c-> <c- k>default</c-><c- p>;</c->
<c- p>};</c-></pre>
      <td bgcolor="#FFCACA">✓
      <td bgcolor="#FFCACA">✓
      <td bgcolor="#FFCACA">✓
      <td bgcolor="#FFCACA">✓
      <td><a href="https://eel.is/c++draft/class.compare#class.spaceship-2.2.sentence-2">deleted</a>
     <tr>
      <td><a href="https://godbolt.org/z/G3ddGeex8">link</a>
      <td>
<pre class="highlight"><c- k>auto</c-> <c- k>operator</c-><c- o>&lt;=></c-><c- p>(</c-><c- k>const</c-> <c- n>M</c-><c- o>&amp;</c-><c- p>)</c-> <c- k>const</c->
  <c- k>noexcept</c-><c- p>(</c->false<c- p>)</c-> <c- o>=</c-> <c- k>default</c-><c- p>;</c-></pre>
      <td>✓
      <td>✓
      <td bgcolor="#FFCACA">noexcept
      <td bgcolor="#FFCACA">incon-<br>sistent
      <td><a href="https://eel.is/c++draft/class.compare#default-note-1">✓</a>
     <tr>
      <td><a href="https://godbolt.org/z/WezedYYE3">link</a>
      <td>
<pre class="highlight"><c- n>C</c-><c- o>&amp;</c-> <c- k>operator</c-><c- o>=</c-><c- p>(</c-><c- n>C</c-><c- o>&amp;</c-><c- p>)</c-> <c- o>=</c-> <c- k>default</c-><c- p>;</c-></pre>
      <td>✓
      <td>✓
      <td>✓
      <td>✓
      <td>✓
     <tr>
      <td><a href="https://godbolt.org/z/hxc9za5KT">link</a>
      <td>
<pre class="highlight"><c- n>C</c-><c- o>&amp;</c-> <c- k>operator</c-><c- o>=</c-><c- p>(</c-><c- k>const</c-> <c- n>C</c-><c- o>&amp;&amp;</c-><c- p>)</c-> <c- o>=</c-> <c- k>default</c-><c- p>;</c-></pre>
      <td>deleted
      <td bgcolor="#FFCACA">✗
      <td bgcolor="#FFCACA">✗
      <td>deleted
      <td><a href="https://eel.is/c++draft/dcl.fct.def.default#2.6">deleted</a>
     <tr>
      <td><a href="https://godbolt.org/z/ojM541bTM">link</a>
      <td>
<pre class="highlight"><c- n>C</c-><c- o>&amp;</c-> <c- k>operator</c-><c- o>=</c-><c- p>(</c-><c- k>const</c-> <c- n>C</c-><c- o>&amp;</c-><c- p>)</c-> <c- k>const</c-> <c- o>=</c-> <c- k>default</c-><c- p>;</c-></pre>
      <td>deleted
      <td bgcolor="#FFCACA">✗
      <td bgcolor="#FFCACA">✗
      <td>deleted
      <td><a href="https://eel.is/c++draft/dcl.fct.def.default#2.6">deleted</a>
     <tr>
      <td><a href="https://godbolt.org/z/hchco3rcK">link</a>
      <td>
<pre class="highlight"><c- n>C</c-><c- o>&amp;</c-> <c- k>operator</c-><c- o>=</c-><c- p>(</c-><c- k>const</c-> <c- n>C</c-><c- o>&amp;</c-><c- p>)</c-> <c- o>&amp;&amp;</c-> <c- o>=</c-> <c- k>default</c-><c- p>;</c-></pre>
      <td>✓
      <td>✓
      <td>✓
      <td>✓
      <td><a href="https://eel.is/c++draft/dcl.fct.def.default#2.1">✓</a><br>(<a data-link-type="biblio" href="#biblio-p2953" title="Forbid defaulting operator=(X&amp;&amp;) &amp;&amp;">[P2953]</a>: deleted)
     <tr>
      <td><a href="https://godbolt.org/z/5P6EKrGjo">link</a>
      <td>
<pre class="highlight"><c- n>C</c-><c- o>&amp;&amp;</c-> <c- k>operator</c-><c- o>=</c-><c- p>(</c-><c- k>const</c-> <c- n>C</c-><c- o>&amp;</c-><c- p>)</c-> <c- o>&amp;&amp;</c-> <c- o>=</c-> <c- k>default</c-><c- p>;</c-></pre>
      <td>✗
      <td>✗
      <td>✗
      <td>✗
      <td><a href="https://eel.is/c++draft/dcl.fct.def.default#2.5">✗</a>
   </table>
   <h3 class="heading settled" data-level="3.7" id="impact"><span class="secno">3.7. </span><span class="content">Impact on existing code</span><a class="self-link" href="#impact"></a></h3>
   <p>There should be little effect on existing code, since this proposal mainly allows syntax that was ill-formed before.
As shown in <a href="#corner-cases">§ 3.6 Existing corner cases</a>, we do propose to change some very arcane examples, e.g.</p>
<pre class="language-cpp highlight"><c- k>struct</c-> <c- nc>C</c-> <c- p>{</c->
  <c- k>const</c-> <c- n>std</c-><c- o>::</c-><c- n>strong_ordering</c-><c- o>&amp;</c->
    <c- k>operator</c-><c- o>&lt;=></c-><c- p>(</c-><c- k>const</c-> <c- n>C</c-><c- o>&amp;</c-><c- p>)</c-> <c- k>const</c-> <c- o>=</c-> <c- k>default</c-><c- p>;</c->
    <c- c1>// Today: Well-formed, non-deleted</c->
    <c- c1>// Tomorrow: Well-formed, deleted</c->
<c- p>};</c->
</pre>
   <h2 class="heading settled" data-level="4" id="experience"><span class="secno">4. </span><span class="content">Implementation experience</span><a class="self-link" href="#experience"></a></h2>
   <p>None yet.</p>
   <h2 class="heading settled" data-level="5" id="polls"><span class="secno">5. </span><span class="content">Straw poll results</span><a class="self-link" href="#polls"></a></h2>
   <p>Arthur O’Dwyer presented P2592R1 in the EWG telecon of 2025-01-08. The following straw polls were taken.
The first was interpreted as "no consensus"; the second was interpreted as consensus (pending electronic polling).</p>
   <table class="def">
    <tbody>
     <tr>
      <th style="width: 70%;">
      <th><strong>SF</strong>
      <th><strong>F</strong>
      <th><strong>N</strong>
      <th><strong>A</strong>
      <th><strong>SA</strong>
     <tr>
      <th><small>EWG prefers this paper contains the change in P2953 <br>(banning explicitly defaulted operator= with rvalue ref-qualifier). <br>[Chair: This means EWG wants to see this paper again.]</small>
      <th> 2 
      <th> 4 
      <th> 9 
      <th> 1 
      <th> 0 
     <tr>
      <th><small>Forward P2952R1 to CWG for inclusion in C++26, pending online polling.</small>
      <th> 3 
      <th> 10 
      <th> 4 
      <th> 1 
      <th> 0 
   </table>
   <h2 class="heading settled" data-level="6" id="wording"><span class="secno">6. </span><span class="content">Proposed wording</span><a class="self-link" href="#wording"></a></h2>
   <h3 class="heading settled" data-level="6.1" id="wording-class.eq"><span class="secno">6.1. </span><span class="content">[class.eq]</span><a class="self-link" href="#wording-class.eq"></a></h3>
   <p class="note" role="note"><b>DRAFTING NOTE:</b> The phrase "equality operator function" (<a href="https://eel.is/c++draft/over.binary">[over.binary]</a>)
means <code class="highlight"><c- o>==</c-></code> or <code class="highlight"><c- o>!=</c-></code>. But <code class="highlight"><c- o>!=</c-></code> is not covered by [class.eq]; it’s covered by [class.compare.secondary] below. </p>
   <p>Modify <a href="https://eel.is/c++draft/class.eq">[class.eq]</a> as follows:</p>
   <p><small></small></p>
   <blockquote>
    <p></p>
    <small> <p><del>1․ A defaulted equality operator function ([over.binary]) shall have a declared return type <code class="highlight"><c- b>bool</c-></code>.</del> </p><p>2․ A defaulted <code class="highlight"><c- o>==</c-></code> operator function for a class <code class="highlight"><c- n>C</c-></code> is defined as deleted unless, for each <code class="highlight"><c- n>x</c-></code><sub><i>i</i></sub> in the expanded list of subobjects for an object <code class="highlight"><c- n>x</c-></code> of type <code class="highlight"><c- n>C</c-></code>, <code class="highlight"><c- n>x</c-></code><sub><i>i</i></sub> <code class="highlight"><c- o>==</c-> <c- n>x</c-></code><sub><i>i</i></sub> is usable
([class.compare.default]).</p> <p>3․ The return value <code class="highlight"><c- n>V</c-></code> of a defaulted <code class="highlight"><c- o>==</c-></code> operator function with parameters <code class="highlight"><c- n>x</c-></code> and <code class="highlight"><c- n>y</c-></code> is determined by comparing corresponding elements <code class="highlight"><c- n>x</c-></code><sub><i>i</i></sub> and <code class="highlight"><c- n>y</c-></code><sub><i>i</i></sub> in the expanded lists of subobjects for <code class="highlight"><c- n>x</c-></code> and <code class="highlight"><c- n>y</c-></code> (in increasing index order)
until the first index <i>i</i> where <code class="highlight"><c- n>x</c-></code><sub><i>i</i></sub> <code class="highlight"><c- o>==</c-></code> <code class="highlight"><c- n>y</c-></code><sub><i>i</i></sub> <del>yields a result value
which</del> , <del>when</del> contextually converted to <code class="highlight"><c- b>bool</c-></code>, yields <code class="highlight">false</code>.
If no such index exists, <code class="highlight"><c- n>V</c-></code> is <code class="highlight">true</code>. Otherwise, <code class="highlight"><c- n>V</c-></code> is <code class="highlight">false</code>.</p> <ins>x․ A defaulted <code class="highlight"><c- o>==</c-></code> operator function shall have the return type <code class="highlight"><c- b>bool</c-></code>. If its declared return type
contains a placeholder type, its return type is deduced as if from <code class="highlight"><c- k>return</c-> true<c- p>;</c-></code>.</ins> <p>4․ [<i>Example 1:</i></p> <pre class="highlight"><c- k>struct</c-> <c- nc>D</c-> <c- p>{</c->
  <c- b>int</c-> <c- n>i</c-><c- p>;</c->
  <c- k>friend</c-> <c- b>bool</c-> <c- k>operator</c-><c- o>==</c-><c- p>(</c-><c- k>const</c-> <c- n>D</c-><c- o>&amp;</c-> <c- n>x</c-><c- p>,</c-> <c- k>const</c-> <c- n>D</c-><c- o>&amp;</c-> <c- n>y</c-><c- p>)</c-> <c- o>=</c-> <c- k>default</c-><c- p>;</c->
      <c- c1>// OK, returns x.i == y.i</c->
<c- p>};</c->
</pre><p>— <i>end example</i>]</p> </small>
   </blockquote>
   <h3 class="heading settled" data-level="6.2" id="wording-class.spaceship"><span class="secno">6.2. </span><span class="content">[class.spaceship]</span><a class="self-link" href="#wording-class.spaceship"></a></h3>
   <p class="note" role="note"><b>DRAFTING NOTE:</b> There are only three "comparison category types" in C++, and <code class="highlight"><c- n>strong_ordering</c-><c- o>::</c-><c- n>equal</c-></code> is implicitly convertible
to all three of them. The status quo already effectively forbids <code class="highlight"><c- o>&lt;=></c-></code> to return a non-comparison-category type,
since either <code class="highlight"><c- n>R</c-></code> is deduced as a common comparison type (which is a comparison category type by definition), or else
a synthesized three-way comparison of type <code class="highlight"><c- n>R</c-></code> must exist (which means <code class="highlight"><c- n>R</c-></code> must be a comparison category type),
or else the sequence <code class="highlight"><c- n>x</c-></code><sub><i>i</i></sub> must be empty (in which case there are no restrictions on <code class="highlight"><c- n>R</c-></code> except
that it be constructible from <code class="highlight"><c- n>strong_ordering</c-><c- o>::</c-><c- n>equal</c-></code>). We strengthen the wording to directly mandate that the
return type be a comparison category type, even in the empty case. </p>
   <p>Modify <a href="https://eel.is/c++draft/class.spaceship">[class.spaceship]</a> as follows:</p>
   <p><small></small></p>
   <blockquote><small> [...]<p></p> <p>2․ Let <code class="highlight"><c- n>R</c-></code> be the declared return type of a defaulted three-way comparison operator function, and let <code class="highlight"><c- n>x</c-></code><sub><i>i</i></sub> be the elements of the expanded list of subobjects for an object <code class="highlight"><c- n>x</c-></code> of type <code class="highlight"><c- n>C</c-></code>.</p> <p>— (2.1) If <code class="highlight"><c- n>R</c-></code> <del>is <code class="highlight"><c- k>auto</c-></code>,</del> <ins>contains a placeholder type,</ins> then let <i>cv<sub>i</sub></i> <code class="highlight"><c- n>R</c-></code><sub><i>i</i></sub> be the type of the expression <code class="highlight"><c- n>x</c-></code><sub><i>i</i></sub> <code class="highlight"><c- o>&lt;=></c-> <c- n>x</c-></code><sub><i>i</i></sub>. The operator function is defined as deleted if that expression is not usable
or if <code class="highlight"><c- n>R</c-></code><sub><i>i</i></sub> is not a comparison category type ([cmp.categories.pre]) for any <i>i</i>.
The return type is deduced as <ins>if from <code class="highlight"><c- k>return</c-> <c- n>Q</c-><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- n>strong_ordering</c-><c- o>::</c-><c- n>equal</c-><c- p>);</c-></code>, where <code class="highlight"><c- n>Q</c-></code> is</ins> the
common comparison type (see below) of <code class="highlight"><c- n>R</c-></code><sub>0</sub>, <code class="highlight"><c- n>R</c-></code><sub>1</sub>, ..., <code class="highlight"><c- n>R</c-></code><sub>n-1</sub>.</p> <p>— (2.2) Otherwise, <del><code class="highlight"><c- n>R</c-></code> shall not contain a placeholder type. If</del> <ins>if</ins> the synthesized three-way comparison of type <code class="highlight"><c- n>R</c-></code> between any objects <code class="highlight"><c- n>x</c-></code><sub><i>i</i></sub> and <code class="highlight"><c- n>x</c-></code><sub><i>i</i></sub> is not defined, the operator function is
defined as deleted.</p> <p>3․ The return value <code class="highlight"><c- n>V</c-></code> <del>of type <code class="highlight"><c- n>R</c-></code></del> of the defaulted three-way comparison operator function with parameters <code class="highlight"><c- n>x</c-></code> and <code class="highlight"><c- n>y</c-></code> <del>of
the same type</del> is determined by comparing corresponding elements <code class="highlight"><c- n>x</c-></code><sub><i>i</i></sub> and <code class="highlight"><c- n>y</c-></code><sub><i>i</i></sub> in the expanded lists of subobjects for <code class="highlight"><c- n>x</c-></code> and <code class="highlight"><c- n>y</c-></code> (in increasing index order) until the first index <i>i</i> where the synthesized three-way comparison of type <code class="highlight"><c- n>R</c-></code> between <code class="highlight"><c- n>x</c-></code><sub><i>i</i></sub> and <code class="highlight"><c- n>y</c-></code><sub><i>i</i></sub> yields a result value <code class="highlight"><c- n>v</c-></code><sub><i>i</i></sub> where <code class="highlight"><c- n>v</c-></code><sub><i>i</i></sub> <code class="highlight"><c- o>!=</c-> <c- mi>0</c-></code>, contextually converted to <code class="highlight"><c- b>bool</c-></code>,
yields <code class="highlight">true</code>; <code class="highlight"><c- n>V</c-></code> is <del>a copy of</del> <code class="highlight"><c- n>v</c-></code><sub><i>i</i></sub>.
If no such index exists, <code class="highlight"><c- n>V</c-></code> is <del><code class="highlight"><c- k>static_cast</c-><c- o>&lt;</c-><c- n>R</c-><c- o>></c-><c- p>(</c-></code></del><code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>strong_ordering</c-><c- o>::</c-><c- n>equal</c-></code><del><code class="highlight"><c- p>)</c-></code></del>.</p> <ins>x․ A defaulted three-way comparison operator function which is not deleted shall have a return type which is a comparison category type
([cmp.categories.pre]).</ins> <p>4․ The <i>common comparison type</i> <code class="highlight"><c- n>U</c-></code> of a possibly-empty list of <i>n</i> comparison category types <code class="highlight"><c- n>T</c-></code><sub>0</sub>, <code class="highlight"><c- n>T</c-></code><sub>1</sub>, ..., <code class="highlight"><c- n>T</c-></code><sub>n-1</sub> is defined as follows:</p> <p>[...]</p> </small></blockquote>
   <h3 class="heading settled" data-level="6.3" id="wording-class.compare.secondary"><span class="secno">6.3. </span><span class="content">[class.compare.secondary]</span><a class="self-link" href="#wording-class.compare.secondary"></a></h3>
   <p>Modify <a href="https://eel.is/c++draft/class.compare.secondary">[class.compare.secondary]</a> as follows:</p>
   <p><small></small></p>
   <blockquote>
    <p></p>
    <small> <p>1․ A <i>secondary comparison operator</i> is a relational operator ([expr.rel]) or the <code class="highlight"><c- o>!=</c-></code> operator. <del>A
defaulted operator function ([over.binary]) for a secondary comparison operator <code class="highlight">@</code> shall have a declared return type <code class="highlight"><c- b>bool</c-></code>.</del> </p><p>2․ <del>The</del> <ins>A defaulted secondary comparison</ins> operator function with parameters <code class="highlight"><c- n>x</c-></code> and <code class="highlight"><c- n>y</c-></code> is defined as deleted if</p> <p>— (2.1) overload resolution ([over.match]), as applied to <code class="highlight"><c- n>x</c-> @ <c- n>y</c-></code>, does not result in a usable candidate, or</p> <p>— (2.2) the candidate selected by overload resolution is not a rewritten candidate.</p> <p>Otherwise, the operator function yields <code class="highlight"><c- n>x</c-> @ <c- n>y</c-></code>. The defaulted operator function is not considered as a candidate
in the overload resolution for the <code class="highlight">@</code> operator.</p> <ins>x․ A defaulted secondary comparison operator function shall have the return type <code class="highlight"><c- b>bool</c-></code>. If its declared return type
contains a placeholder type, its return type is deduced as if from <code class="highlight"><c- k>return</c-> true<c- p>;</c-></code>.</ins> <p>3․ [<i>Example 1</i>:</p> <pre class="highlight"><c- k>struct</c-> <c- nc>HasNoLessThan</c-> <c- p>{</c-> <c- p>};</c->

<c- k>struct</c-> <c- nc>C</c-> <c- p>{</c->
  <c- k>friend</c-> <c- n>HasNoLessThan</c-> <c- k>operator</c-><c- o>&lt;=></c-><c- p>(</c-><c- k>const</c-> <c- n>C</c-><c- o>&amp;</c-><c- p>,</c-> <c- k>const</c-> <c- n>C</c-><c- o>&amp;</c-><c- p>);</c->
  <c- b>bool</c-> <c- k>operator</c-><c- o>&lt;</c-><c- p>(</c-><c- k>const</c-> <c- n>C</c-><c- o>&amp;</c-><c- p>)</c-> <c- k>const</c-> <c- o>=</c-> <c- k>default</c-><c- p>;</c-> <c- c1>// OK, function is deleted</c->
<c- p>};</c->
</pre><p>— <i>end example</i>]</p> </small>
   </blockquote>
   <h3 class="heading settled" data-level="6.4" id="wording-class.copy.assign"><span class="secno">6.4. </span><span class="content">[class.copy.assign]</span><a class="self-link" href="#wording-class.copy.assign"></a></h3>
   <p class="note" role="note"><b>DRAFTING NOTE:</b> <a href="https://eel.is/c++draft/class.copy.assign#6.sentence-1">[class.copy.assign]/6</a> already clearly states that "The implicitly-declared copy/move assignment operator for class <code class="highlight"><c- n>X</c-></code> has the return type <code class="highlight"><c- n>X</c-><c- o>&amp;</c-></code>."
But we need this new wording to ensure that an <em>explicitly-defaulted</em> copy/move assignment operator
will deduce that same type. (If it deduces a different type, then the explicitly-defaulted operator
becomes ill-formed, as in example <code class="highlight"><c- n>B</c-></code> below.) </p>
   <p>Modify <a href="https://eel.is/c++draft/class.copy.assign">[class.copy.assign]</a> as follows:</p>
   <p><small></small></p>
   <blockquote><small> 14․ The implicitly-defined copy/move assignment operator for a class returns
the object for which the assignment operator is invoked, that is,
the object assigned to.<p></p> <p><ins>15․ If a defaulted copy/move assignment operator’s declared return type contains a
placeholder type, its return type is deduced as if from <code class="highlight"><c- k>return</c-> <c- n>r</c-><c- p>;</c-></code>, where <code class="highlight"><c- n>r</c-></code> is an lvalue
reference to the object for which the assignment operator is invoked.</ins> </p><p><ins>16․ [<i>Example:</i></ins> </p><pre class="highlight"><ins><c- k>struct</c-> <c- nc>A</c-> <c- p>{</c-></ins>
  <ins><c- k>decltype</c-><c- p>(</c-><c- k>auto</c-><c- p>)</c-> <c- k>operator</c-><c- o>=</c-><c- p>(</c-><c- n>A</c-><c- o>&amp;&amp;</c-><c- p>)</c-> <c- o>=</c-> <c- k>default</c-><c- p>;</c-></ins>
    <ins><i><c- c1>// Return type is A&amp;</c-></i></ins>
<ins><c- p>};</c-></ins>
<ins><c- k>struct</c-> <c- nc>B</c-> <c- p>{</c-></ins>
  <ins><c- k>auto</c-> <c- k>operator</c-><c- o>=</c-><c- p>(</c-><c- n>B</c-><c- o>&amp;&amp;</c-><c- p>)</c-> <c- o>=</c-> <c- k>default</c-><c- p>;</c-></ins>
    <ins><i><c- c1>// error: Return type is B, which violates [dcl.fct.def.default]/2.5</c-></i></ins>
<ins><c- p>};</c-></ins>
</pre><ins>—<i>end example</i>]</ins> </small></blockquote>
  </main>
<script>
(function() {
  "use strict";
  var collapseSidebarText = '<span aria-hidden="true">←</span> '
                          + '<span>Collapse Sidebar</span>';
  var expandSidebarText   = '<span aria-hidden="true">→</span> '
                          + '<span>Pop Out Sidebar</span>';
  var tocJumpText         = '<span aria-hidden="true">↑</span> '
                          + '<span>Jump to Table of Contents</span>';

  var sidebarMedia = window.matchMedia('screen and (min-width: 78em)');
  var autoToggle   = function(e){ toggleSidebar(e.matches) };
  if(sidebarMedia.addListener) {
    sidebarMedia.addListener(autoToggle);
  }

  function toggleSidebar(on) {
    if (on == undefined) {
      on = !document.body.classList.contains('toc-sidebar');
    }

    /* Don't scroll to compensate for the ToC if we're above it already. */
    var headY = 0;
    var head = document.querySelector('.head');
    if (head) {
      // terrible approx of "top of ToC"
      headY += head.offsetTop + head.offsetHeight;
    }
    var skipScroll = window.scrollY < headY;

    var toggle = document.getElementById('toc-toggle');
    var tocNav = document.getElementById('toc');
    if (on) {
      var tocHeight = tocNav.offsetHeight;
      document.body.classList.add('toc-sidebar');
      document.body.classList.remove('toc-inline');
      toggle.innerHTML = collapseSidebarText;
      if (!skipScroll) {
        window.scrollBy(0, 0 - tocHeight);
      }
      tocNav.focus();
      sidebarMedia.addListener(autoToggle); // auto-collapse when out of room
    }
    else {
      document.body.classList.add('toc-inline');
      document.body.classList.remove('toc-sidebar');
      toggle.innerHTML = expandSidebarText;
      if (!skipScroll) {
        window.scrollBy(0, tocNav.offsetHeight);
      }
      if (toggle.matches(':hover')) {
        /* Unfocus button when not using keyboard navigation,
           because I don't know where else to send the focus. */
        toggle.blur();
      }
    }
  }

  function createSidebarToggle() {
    /* Create the sidebar toggle in JS; it shouldn't exist when JS is off. */
    var toggle = document.createElement('a');
      /* This should probably be a button, but appearance isn't standards-track.*/
    toggle.id = 'toc-toggle';
    toggle.class = 'toc-toggle';
    toggle.href = '#toc';
    toggle.innerHTML = collapseSidebarText;

    sidebarMedia.addListener(autoToggle);
    var toggler = function(e) {
      e.preventDefault();
      sidebarMedia.removeListener(autoToggle); // persist explicit off states
      toggleSidebar();
      return false;
    }
    toggle.addEventListener('click', toggler, false);


    /* Get <nav id=toc-nav>, or make it if we don't have one. */
    var tocNav = document.getElementById('toc-nav');
    if (!tocNav) {
      tocNav = document.createElement('p');
      tocNav.id = 'toc-nav';
      /* Prepend for better keyboard navigation */
      document.body.insertBefore(tocNav, document.body.firstChild);
    }
    /* While we're at it, make sure we have a Jump to Toc link. */
    var tocJump = document.getElementById('toc-jump');
    if (!tocJump) {
      tocJump = document.createElement('a');
      tocJump.id = 'toc-jump';
      tocJump.href = '#toc';
      tocJump.innerHTML = tocJumpText;
      tocNav.appendChild(tocJump);
    }

    tocNav.appendChild(toggle);
  }

  var toc = document.getElementById('toc');
  if (toc) {
    createSidebarToggle();
    toggleSidebar(sidebarMedia.matches);

    /* If the sidebar has been manually opened and is currently overlaying the text
       (window too small for the MQ to add the margin to body),
       then auto-close the sidebar once you click on something in there. */
    toc.addEventListener('click', function(e) {
      if(e.target.tagName.toLowerCase() == "a" && document.body.classList.contains('toc-sidebar') && !sidebarMedia.matches) {
        toggleSidebar(false);
      }
    }, false);
  }
  else {
    console.warn("Can't find Table of Contents. Please use <nav id='toc'> around the ToC.");
  }

  /* Wrap tables in case they overflow */
  var tables = document.querySelectorAll(':not(.overlarge) > table.data, :not(.overlarge) > table.index');
  var numTables = tables.length;
  for (var i = 0; i < numTables; i++) {
    var table = tables[i];
    var wrapper = document.createElement('div');
    wrapper.className = 'overlarge';
    table.parentNode.insertBefore(wrapper, table);
    wrapper.appendChild(table);
  }

})();
</script>
  <h2 class="no-num no-ref heading settled" id="references"><span class="content">References</span><a class="self-link" href="#references"></a></h2>
  <h3 class="no-num no-ref heading settled" id="informative"><span class="content">Informative References</span><a class="self-link" href="#informative"></a></h3>
  <dl>
   <dt id="biblio-cwg2586">[CWG2586]
   <dd>Barry Revzin. <a href="https://cplusplus.github.io/CWG/issues/2586.html"><cite>Explicit object parameter for assignment and comparison</cite></a>. May–July 2022. URL: <a href="https://cplusplus.github.io/CWG/issues/2586.html">https://cplusplus.github.io/CWG/issues/2586.html</a>
   <dt id="biblio-p0847">[P0847]
   <dd>Sy Brand; et al. <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p0847r7.html"><cite>Deducing this</cite></a>. July 2021. URL: <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p0847r7.html">https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p0847r7.html</a>
   <dt id="biblio-p1046r2">[P1046R2]
   <dd>David Stone. <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p1046r2.html"><cite>Automatically Generate More Operators</cite></a>. January 2020. URL: <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p1046r2.html">https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p1046r2.html</a>
   <dt id="biblio-p2953">[P2953]
   <dd>Arthur O'Dwyer. <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2953r0.html"><cite>Forbid defaulting operator=(X&amp;&amp;) &amp;&amp;</cite></a>. August 2023. URL: <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2953r0.html">https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2953r0.html</a>
  </dl>