<!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>P3668R1: Defaulting Postfix Increment and Decrement Operations</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 b25686b9f, updated Fri Mar 14 14:15:20 2025 -0700" name="generator">
  <link href="https://isocpp.org/favicon.ico" rel="icon">
  <meta content="dark light" name="color-scheme">
<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">P3668R1<br>Defaulting Postfix Increment and Decrement Operations</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-04-28">2025-04-28</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:mjtaylor214@hotmail.com">Matthew Taylor</a>
     <dd class="editor p-author h-card vcard"><a class="p-name fn u-email email" href="mailto:waffl3x@baylibre.com">Alex</a>
     <dt>Audience:
     <dd>SG17
     <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>Postfix increment and decrement operators have a near-universal canonical definition. We propose that this default should be codified into the language by being able to <code class="highlight"><c- o>=</c-> <c- k>default</c-></code> such operators.</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="#revision-history"><span class="secno">1</span> <span class="content">Revision History</span></a>
     <ol class="toc">
      <li><a href="#change-from-r0"><span class="secno">1.1</span> <span class="content">Changes from R0:</span></a>
     </ol>
    <li><a href="#motivation-and-scope"><span class="secno">2</span> <span class="content">Motivation and Scope</span></a>
    <li>
     <a href="#proposal"><span class="secno">3</span> <span class="content">Proposal</span></a>
     <ol class="toc">
      <li>
       <a href="#proposal-edges"><span class="secno">3.1</span> <span class="content">Minor Edge Cases</span></a>
       <ol class="toc">
        <li><a href="#proposal-volatile"><span class="secno">3.1.1</span> <span class="content">Volatile Qualification</span></a>
        <li><a href="#proposal-prefix-return"><span class="secno">3.1.2</span> <span class="content">Return type of the prefix increment operator</span></a>
        <li><a href="#proposal-xobj-param"><span class="secno">3.1.3</span> <span class="content">Explicit Object Parameter Types</span></a>
       </ol>
      <li><a href="#proposal-function-body"><span class="secno">3.2</span> <span class="content"><code class="highlight"><c- o>=</c-> <c- k>default</c-></code> is a function body</span></a>
     </ol>
    <li>
     <a href="#prior-art"><span class="secno">4</span> <span class="content">Prior Art</span></a>
     <ol class="toc">
      <li><a href="#prior-crtp"><span class="secno">4.1</span> <span class="content">Template Solutions via CRTP</span></a>
      <li><a href="#prior-reflection"><span class="secno">4.2</span> <span class="content">Reflection Solutions</span></a>
      <li><a href="#prior-free-template"><span class="secno">4.3</span> <span class="content">Free function template <code class="highlight"><c- k>operator</c-><c- o>++</c-><c- p>(</c-><c- n>T</c-><c- o>&amp;</c-><c- p>,</c-> <c- b>int</c-><c- p>)</c-></code></span></a>
      <li><a href="#prior-P1046"><span class="secno">4.4</span> <span class="content">Automatically Generating More Operators</span></a>
     </ol>
    <li>
     <a href="#alternatives"><span class="secno">5</span> <span class="content">Alternatives Considered</span></a>
     <ol class="toc">
      <li><a href="#alternative-rewrite"><span class="secno">5.1</span> <span class="content">Rewrite Rule</span></a>
      <li><a href="#alternative-semantics"><span class="secno">5.2</span> <span class="content">Supporting Alternative Semantics for Postfix Increment on Iterators</span></a>
      <li><a href="#alternative-templates"><span class="secno">5.3</span> <span class="content">Defaulting Templates</span></a>
     </ol>
    <li>
     <a href="#others"><span class="secno">6</span> <span class="content">Other Papers in this Space</span></a>
     <ol class="toc">
      <li><a href="#others-P3662"><span class="secno">6.1</span> <span class="content">P3662: Improve Increment and Decrement Operator Syntax</span></a>
      <li><a href="#others-P2952"><span class="secno">6.2</span> <span class="content">P2952: auto&amp; operator=(X&amp;&amp;) = default</span></a>
     </ol>
    <li><a href="#existing"><span class="secno">7</span> <span class="content">Effect on Existing Code</span></a>
    <li><a href="#implementation"><span class="secno">8</span> <span class="content">Implementation Experience</span></a>
    <li>
     <a href="#wording"><span class="secno">9</span> <span class="content">Proposed Wording</span></a>
     <ol class="toc">
      <li><a href="#wording-P2952"><span class="secno">9.1</span> <span class="content">Wording relative to P2952</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="revision-history"><span class="secno">1. </span><span class="content">Revision History</span><a class="self-link" href="#revision-history"></a></h2>
   <h3 class="heading settled" data-level="1.1" id="change-from-r0"><span class="secno">1.1. </span><span class="content">Changes from R0:</span><a class="self-link" href="#change-from-r0"></a></h3>
   <ul>
    <li data-md>
     <p>Added discussion of what you can already do in defaulted functions (<a href="#proposal-function-body">§ 3.2 = default is a function body</a>) following BSI feedback.</p>
    <li data-md>
     <p>Added discussion of the potential to reduce boilerplate further via defaulting templates (<a href="#alternative-templates">§ 5.3 Defaulting Templates</a>) following BSI feedback.</p>
    <li data-md>
     <p>Fix to typo in wording.</p>
   </ul>
   <h2 class="heading settled" data-level="2" id="motivation-and-scope"><span class="secno">2. </span><span class="content">Motivation and Scope</span><a class="self-link" href="#motivation-and-scope"></a></h2>
    Postfix increment and decrement operators have a default behaviour which already exists in the mind of every C++ developer - make a copy, increment/decrement the original, and return the copy. The canonical implementation of this default can always be expressed entirely in terms of other operations (prefix increment/decrement and copy-construction), in a manner which is entirely agnostic to any other members or subobjects of the class, e.g. 
<pre class="language-cpp highlight"><c- k>auto</c-> <c- n>copy</c-><c- p>{</c-><c- o>*</c-><c- k>this</c-><c- p>};</c->
<c- o>++*</c-><c- k>this</c-><c- p>;</c->
<c- k>return</c-> <c- n>copy</c-><c- p>;</c->
</pre>
   <p>We propose that this sensible default be codified into the language.</p>
   <p>Since C++11 the language has had a mechanism in <code class="highlight"><c- o>=</c-> <c- k>default</c-></code> for expressing that a function has its default semantics in order to save the user from repetitive boilerplate. Our proposal is that postfix increment and decrement operators should be defaultable.</p>
   <table>
    <tbody>
     <tr>
      <th>Currently
      <th>With Proposal
     <tr>
      <td>
<pre class="language-cpp highlight"><c- k>class</c-> <c- nc>foo</c-><c- p>{</c->
    <c- b>int</c-> <c- n>member</c-><c- p>;</c->
<c- k>public</c-><c- o>:</c->
    <c- k>constexpr</c-> <c- n>foo</c-><c- o>&amp;</c-> <c- k>operator</c-><c- o>++</c-><c- p>(){</c->
        <c- o>++</c-><c- n>member</c-><c- p>;</c->
        <c- k>return</c-> <c- o>*</c-><c- k>this</c-><c- p>;</c->
    <c- p>}</c->
    <c- k>constexpr</c-> <c- n>foo</c-> <c- k>operator</c-><c- o>++</c-><c- p>(</c-><c- b>int</c-><c- p>){</c->
        <c- k>auto</c-> <c- n>copy</c-><c- p>{</c-><c- o>*</c-><c- k>this</c-><c- p>};</c->
        <c- k>this</c-><c- o>-></c-><c- k>operator</c-><c- o>++</c-><c- p>();</c->
        <c- k>return</c-> <c- n>copy</c-><c- p>;</c->
    <c- p>}</c->
<c- p>};</c->
</pre>
      <td>
<pre class="language-cpp highlight"><c- k>class</c-> <c- nc>foo</c-><c- p>{</c->
    <c- b>int</c-> <c- n>member</c-><c- p>;</c->
<c- k>public</c-><c- o>:</c->
    <c- k>constexpr</c-> <c- n>foo</c-><c- o>&amp;</c-> <c- k>operator</c-><c- o>++</c-><c- p>(){</c->
        <c- o>++</c-><c- n>member</c-><c- p>;</c->
        <c- k>return</c-> <c- o>*</c-><c- k>this</c-><c- p>;</c->
    <c- p>}</c->
    <c- k>constexpr</c-> <c- n>foo</c-> <c- k>operator</c-><c- o>++</c-><c- p>(</c-><c- b>int</c-><c- p>)</c-> <c- o>=</c-> <c- k>default</c-><c- p>;</c->
<c- p>};</c->
</pre>
   </table>
   <p>This reduces boilerplate code while still expressing the universally-known meaning of the function. The majority of classes written with postfix operations can now simply default them and get an operator which does the right thing. It reduces the possibility for user error when writing such operators - typical classes won’t need their implementation of such functions checked and debugged; and atypical ones will have their explicitly-defined operators stand out by virtue of not being defaulted.</p>
   <p>Standardising a "default" behaviour for postfix operations would also allow us to shrink the library specification, by expressing operations which are specified to be equivalent to the canonical implementation as being default. This paper does not propose this at this time, but the authors intend to bring a paper to propose this pending interest in the language feature and have identified 49 candidate operations which could be defaulted and remain semantically equivalent to their current behaviour.</p>
   <p class="note" role="note"><span class="marker">Note:</span> Most of the examples in this paper are written in terms of the postfix increment operator. The scope of this paper equally covers the postfix decrement operator, however we do not repeat every example for both operators in the interests of saving reader time.</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>
    We propose that the postfix increment operator be a defaultable operator. On an instance <code class="highlight"><c- n>c</c-></code> of a class of type <code class="highlight"><c- n>C</c-></code>, the default behaviour should be equivalent to 
<pre class="language-cpp highlight"><c- n>C</c-> <c- n>tmp</c-> <c- o>=</c-> <c- n>C</c-><c- p>{</c-><c- n>c</c-><c- p>};</c->
<c- o>++</c-><c- n>c</c-><c- p>;</c->
<c- k>return</c-> <c- n>tmp</c-><c- p>;</c->
</pre>
   <p>We also propose that the postfix decrement operator be a defaultable operator, with the defaulted behaviour being equivalent to</p>
<pre class="language-cpp highlight"><c- n>C</c-> <c- n>tmp</c-> <c- o>=</c-> <c- n>C</c-><c- p>{</c-><c- n>c</c-><c- p>};</c->
<c- o>--</c-><c- n>c</c-><c- p>;</c->
<c- k>return</c-> <c- n>tmp</c-><c- p>;</c->
</pre>
   <p>In both cases, if the defaulted function does not have return type <code class="highlight"><c- n>C</c-></code>, or if <code class="highlight"><c- n>C</c-></code> is not complete in the context in which the function is defined as defaulted, the program is ill-formed.</p>
   <p>Note that in order to write a specification which applies to all permutations of the postfix operator, we cannot refer to <code class="highlight"><c- k>this</c-></code>; as it is possible to define postfix <code class="highlight"><c- k>operator</c-><c- o>++</c-></code> and <code class="highlight"><c- k>operator</c-><c- o>--</c-></code> as free functions or functions with an explicit object parameter. For example, we are proposing that all of the below postfix operations should be defaultable:</p>
<pre class="language-cpp highlight"><c- k>struct</c-> <c- nc>S0</c-> <c- p>{</c->
  <c- b>int</c-> <c- n>v</c-><c- p>;</c->
  <c- n>S0</c-><c- o>&amp;</c-> <c- k>operator</c-><c- o>++</c-><c- p>()</c-> <c- p>{</c-> <c- o>++</c-><c- n>v</c-><c- p>;</c-> <c- k>return</c-> <c- o>*</c-><c- k>this</c-><c- p>;</c-> <c- p>}</c->
  <c- n>S0</c-> <c- k>operator</c-><c- o>++</c-><c- p>(</c-><c- b>int</c-><c- p>)</c-> <c- o>=</c-> <c- k>default</c-><c- p>;</c->
<c- p>};</c->

<c- k>struct</c-> <c- nc>S1</c-> <c- p>{</c->
  <c- b>int</c-> <c- n>v</c-><c- p>;</c->
  <c- n>S1</c-><c- o>&amp;</c-> <c- k>operator</c-><c- o>++</c-><c- p>()</c-> <c- p>{</c-> <c- o>++</c-><c- n>v</c-><c- p>;</c-> <c- k>return</c-> <c- o>*</c-><c- k>this</c-><c- p>;</c-> <c- p>}</c->
  <c- n>S1</c-> <c- k>operator</c-><c- o>++</c-><c- p>(</c-><c- k>this</c-> <c- n>S1</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- p>};</c->

<c- k>struct</c-> <c- nc>S2</c-> <c- p>{</c->
  <c- b>int</c-> <c- n>v</c-><c- p>;</c->
  <c- n>S2</c-><c- o>&amp;</c-> <c- k>operator</c-><c- o>++</c-><c- p>()</c-> <c- p>{</c-> <c- o>++</c-><c- n>v</c-><c- p>;</c-> <c- k>return</c-> <c- o>*</c-><c- k>this</c-><c- p>;</c-> <c- p>}</c->
<c- p>};</c->
<c- n>S2</c-> <c- k>operator</c-><c- o>++</c-><c- p>(</c-><c- n>S2</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->
</pre>
   <p>If <code class="highlight"><c- n>C</c-></code> does not have a copy constructor and corresponding prefix operation which is accessible from the context of the body of the defaulted function, it is defined as deleted. Unlike the comparison operators, it is not required for a free function postfix operator to be a friend of the class on which it is operating. <code class="highlight"><c- k>operator</c-><c- o>++</c-><c- p>(</c-><c- b>int</c-><c- p>)</c-></code> does not need to access the subobjects of the class in order to use its copy constructor or prefix operator, so making it a <code class="highlight"><c- k>friend</c-></code> seems an unecessary requirement. This decision does, however, rule out some very arcane examples of defaulting the postfix operator, such as:</p>
<pre class="language-cpp highlight"><c- k>class</c-> <c- nc>foo</c-><c- p>{</c->
  <c- c1>//Private</c->
    <c- n>foo</c-><c- p>(</c-><c- k>const</c-> <c- n>foo</c-><c- o>&amp;</c-><c- p>);</c->
    <c- n>foo</c-><c- o>&amp;</c-> <c- k>operator</c-><c- o>++</c-><c- p>();</c->
<c- p>};</c->

<c- c1>//Defined as deleted</c->
<c- n>foo</c-> <c- k>operator</c-><c- o>++</c-><c- p>(</c-><c- n>foo</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->
</pre>
   <p>Note that our spelling of initialization syntax of the copy is very slightly different from how the library wording specifies postfix operations on existing iterators, e.g. <a href="https://eel.is/c++draft/istream.iterator.ops#9">[istream.iterator.ops]</a>, to account for the possibility of a user-defined class defining its copy constructor as <code class="highlight"><c- k>explicit</c-></code>. As the default meaning of a postfix operator is widely known to invoke a copy, a user who explicitly opts into that default meaning should be considered to have consented to a copy being created.</p>
   <h3 class="heading settled" data-level="3.1" id="proposal-edges"><span class="secno">3.1. </span><span class="content">Minor Edge Cases</span><a class="self-link" href="#proposal-edges"></a></h3>
   <p>Many details of the behaviour of defaulted operators is already covered in <a href="https://eel.is/c++draft/dcl.fct.def.default">[dcl.fct.def.default]</a> and we not intend to change the existing behaviour. However there are a handful of small edge cases to consider in this design. Our baseline to determine how a defaulted postfix operator should behave is to consider the behaviour when <code class="highlight"><c- o>=</c-> <c- k>default</c-></code> is replaced with the three-line canonical definition. If it results in well-formed code with the correct semantics we consider it valid; and if it does not, we do not. However, some notable cases include:</p>
   <h4 class="heading settled" data-level="3.1.1" id="proposal-volatile"><span class="secno">3.1.1. </span><span class="content">Volatile Qualification</span><a class="self-link" href="#proposal-volatile"></a></h4>
   <p><code class="highlight"><c- k>volatile</c-></code> increment and decrement operations are deprecated as of <a data-link-type="biblio" href="#biblio-p1152" title="Deprecating volatile">[P1152]</a>. We do not intend to break with the status quo, so consider that defaulted postfix operations acting on a <code class="highlight"><c- k>volatile</c-></code> object are permitted, but deprecated.</p>
   <h4 class="heading settled" data-level="3.1.2" id="proposal-prefix-return"><span class="secno">3.1.2. </span><span class="content">Return type of the prefix increment operator</span><a class="self-link" href="#proposal-prefix-return"></a></h4>
   <p>It is possible for the user to define a prefix increment operator for class <code class="highlight"><c- n>C</c-></code> which has a different return type from the expected default of <code class="highlight"><c- n>C</c-><c- o>&amp;</c-></code>. It may be tempting when specifying a default postfix operation to require that the prefix operation must always return <code class="highlight"><c- n>C</c-><c- o>&amp;</c-></code> out of a desire to ensure that it does the right thing and prevent the generated default postfix operation from exhibiting surprising behaviour.</p>
   <p>However, the return type of the prefix operator function alone is not enough to guarantee it does a "canonical" operation - it may return a surprising value (e.g. a reference to some other instance of <code class="highlight"><c- n>C</c-></code>).
The compiler cannot look ahead to the definition of a declared prefix operation, which may be in some other TU, at the point of injecting a defaulted postfix definition; and even if we were to require that the full definition be visible, it could not in general prove that the returned value is the correct one.
As such, it is impossible to specify that the prefix operator must always return a correct reference to the correct object. Additionally, the canonical implementation discards the return value of the prefix operator in all cases.</p>
   <p>With this in mind, we do not impose requirements on the return type of the prefix operator.</p>
   <h4 class="heading settled" data-level="3.1.3" id="proposal-xobj-param"><span class="secno">3.1.3. </span><span class="content">Explicit Object Parameter Types</span><a class="self-link" href="#proposal-xobj-param"></a></h4>
   <p>There exists an occasionally-surprising feature of explicit object parameters, namely that the explicit object parameter is not required to be the type of the class on which the function is called. For example, the following code is well-formed:</p>
<pre class="language-cpp highlight"><c- k>struct</c-> <c- nc>S</c-> <c- p>{</c->
    <c- k>operator</c-> <c- b>int</c-><c- p>()</c-> <c- p>{</c-> <c- k>return</c-> <c- mi>42</c-><c- p>;</c-> <c- p>}</c->
    <c- k>auto</c-> <c- k>operator</c-><c- o>++</c-><c- p>(</c-><c- k>this</c-> <c- b>int</c-><c- p>,</c-> <c- b>int</c-><c- p>)</c-> <c- p>{</c-> <c- d>/*...*/</c-> <c- p>}</c->
<c- p>};</c->
</pre>
   <p>Which raises the question of whether such an operator should be defaultable. In such cases, a canonical function definition for postfix increment would still generate well-formed code. However, this does not follow the canonical semantics of a default postfix operation, so should not be valid behaviour when specifying that a class has the default semantics.</p>
   <p>Fortunately, this possibility is already accounted for in the current standard. Wording in <a href="https://eel.is/c++draft/dcl.fct.def.default#2.2">[dcl.fct.def.default]</a> requires that explicit object parameters of defaulted special member functions have type "reference to <code class="highlight"><c- n>C</c-></code>". While postfix increment and decrement operators are not special member functions; we see no reason to break with the existing intent and allow other types of explicit object parameters there. As such, if the explicit object parameter is not of a reference type to <code class="highlight"><c- n>C</c-></code>, the program is ill-formed.</p>
   <h3 class="heading settled" data-level="3.2" id="proposal-function-body"><span class="secno">3.2. </span><span class="content"><code class="highlight"><c- o>=</c-> <c- k>default</c-></code> is a function body</span><a class="self-link" href="#proposal-function-body"></a></h3>
    It is worth noting that <code class="highlight"><c- o>=</c-> <c- k>default</c-></code> is just a function body which the implementation uses to inject the "default" semantics. It does not constrain the grammar of the function declaration. Defaulted functions are just as able to be marked as <code class="highlight"><c- k>noexcept</c-></code>, to be constrained by <code class="highlight"><c- k>requires</c-></code> clauses, or to feature other declaration-level constructs as their non-defaulted counterparts. We do not intend to change this, but we mention it to highlight that we do not need any further grammar changes to permit code such as the following: 
<pre class="language-cpp highlight"><c- k>template</c-><c- o>&lt;</c-><c- k>typename</c-> <c- nc>Range</c-><c- o>></c->
<c- k>class</c-> <c- nc>my_generic_iterator</c-><c- p>{</c->
    <c- c1>//...</c->
    <c- n>my_generic_iterator</c-> <c- k>operator</c-><c- o>++</c-><c- p>(</c-><c- b>int</c-><c- p>)</c-> <c- k>requires</c-> <c- n>std</c-><c- o>::</c-><c- n>ranges</c-><c- o>::</c-><c- n>forward_range</c-><c- o>&lt;</c-><c- n>Range</c-><c- o>></c-> <c- o>=</c-> <c- k>default</c-><c- p>;</c->
    <c- n>my_generic_iterator</c-> <c- k>operator</c-><c- o>++</c-><c- p>(</c-><c- b>int</c-><c- p>){</c-> <c- d>/*...*/</c-> <c- p>}</c->
<c- p>};</c->
</pre>
   <p>Equally, the mechanism to <code class="highlight"><c- o>=</c-> <c- k>default</c-></code> postfix operations has no magic associated which might itself affect overload resolution. If the user does not declare a postfix operation for their class, no part of this proposal will generate rewritten candidates to make postfix operations valid. And, while it is not necessary, if the user wishes to be explicit that their class does not support postfix operations, they still have the option to explicitly delete the function.</p>
   <h2 class="heading settled" data-level="4" id="prior-art"><span class="secno">4. </span><span class="content">Prior Art</span><a class="self-link" href="#prior-art"></a></h2>
    There are several existing approaches to attempt a similar reduction in boilerplate. Our position is that none of them quite find the best way to express user intent in code, and will examine them here. 
   <h3 class="heading settled" data-level="4.1" id="prior-crtp"><span class="secno">4.1. </span><span class="content">Template Solutions via CRTP</span><a class="self-link" href="#prior-crtp"></a></h3>
    It is possible in current C++ to define a mixin class to attach the canonical postfix operation to derived classes, such as 
<pre class="language-cpp highlight"><c- k>struct</c-> <c- nc>incrementable</c-><c- p>{</c->
  <c- k>constexpr</c-> <c- k>auto</c-> <c- k>operator</c-><c- o>++</c-><c- p>(</c-><c- k>this</c-> <c- k>auto</c-><c- o>&amp;</c-> <c- n>self</c-><c- p>,</c-> <c- b>int</c-><c- p>){</c->
    <c- k>auto</c-> <c- n>cpy</c-><c- p>{</c-><c- n>self</c-><c- p>};</c->
    <c- o>++</c-><c- n>self</c-><c- p>;</c->
    <c- k>return</c-> <c- n>cpy</c-><c- p>;</c->
  <c- p>}</c->
<c- p>};</c->

<c- k>class</c-> <c- nc>my_class</c-> <c- o>:</c-> <c- k>public</c-> <c- n>incrementable</c-><c- p>{</c->
  <c- c1>//...</c->
  <c- k>auto</c-><c- o>&amp;</c-> <c- k>operator</c-><c- o>++</c-><c- p>(){</c-><c- d>/*....*/</c-><c- p>}</c->
	
  <c- k>using</c-> <c- n>incrementable</c-><c- o>::</c-><c- k>operator</c-><c- o>++</c-><c- p>;</c->
<c- p>};</c->
</pre>
   <p>Where <code class="highlight"><c- n>my_class</c-></code> will inherit a postfix increment operation from <code class="highlight"><c- n>incrementable</c-></code> which follows the canonical definition. This is a good solution, and indeed something similar to this is proposed in <a data-link-type="biblio" href="#biblio-p2727" title="std::iterator_interface">[P2727]</a>, but we find that it is still suboptimal. Every parent class which inherits from <code class="highlight"><c- n>incrementable</c-></code> must explicitly make the postfix operator visible with a <code class="highlight"><c- k>using</c-></code> expression, as the prefix operator in <code class="highlight"><c- n>my_class</c-></code> shadows the postfix in <code class="highlight"><c- n>incrementable</c-></code>. Mixins open the door to potentially confusing semantics, such as <code class="highlight"><c- n>my_class</c-></code> being pointer-interconvertible with <code class="highlight"><c- n>incrementable</c-></code>; and ultimately the user must still intrude into their class to place a declaration which might result in the canonical definition being applied but is counter-intuitively spelled as a <code class="highlight"><c- k>using</c-></code> declaration.</p>
   <h3 class="heading settled" data-level="4.2" id="prior-reflection"><span class="secno">4.2. </span><span class="content">Reflection Solutions</span><a class="self-link" href="#prior-reflection"></a></h3>
   <p><a data-link-type="biblio" href="#biblio-p3294" title="Code Injection with Token Sequences">[P3294]</a> notes that generative reflection, when it arrives, could also be used to append postfix operations to classes by defining a metafunction to do the canonical thing, such that a user might:</p>
<pre class="language-cpp 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>auto</c-> <c- k>operator</c-><c- o>++</c-><c- p>()</c-> <c- o>-></c-> <c- n>C</c-><c- o>&amp;</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>consteval</c-> <c- p>{</c-> <c- n>postfix_increment</c-><c- p>();</c-> <c- p>}</c->
<c- p>};</c->
</pre>
   <p>This solution is analogous to the previous example - in both cases the user must define some other code elsewhere to manually implement the canonical operations and place a declaration in their class to attach those operations to it. As before, is a less direct way of spelling what this paper proposes - what the user really wants to say is "give me the default postfix operation"; and C++ already has a standard spelling for this with <code class="highlight"><c- o>=</c-> <c- k>default</c-></code>. We argue that such reflection-based solutions are well suited for specific problems where the user wishes to ensure that generated code can be programmatically tailored to the particular nature of the problem at hand or family of classes into which the definitions are intended to be injected. However, we seek to provide a general solution based on the universal default semantics of postfix operations. Doing this does not prevent the user from using reflection to generate more fine-grained solutions when that is the correct tool for the job, but the possibility of generative reflection does not prevent us from recognising the canonical default and providing a general solution.</p>
   <p>There is also benefit in standardising the way to retrieve this default - multiple libraries might all ship their own <code class="highlight"><c- n>incrementable</c-></code> or <code class="highlight"><c- n>postfix_increment</c-><c- p>()</c-></code> variants, which may make slightly different design choices. For example, a library may choose to support increment, decrement, or both; or attempt to deduce properties of the class to which its its operations are applied change behaviour accordingly. This runs the risk of cluttering code which uses them with several similar-sounding names which correspond to subtly different semantics; whereas <code class="highlight"><c- n>C</c-> <c- k>operator</c-><c- o>++</c-><c- p>(</c-><c- b>int</c-><c- p>)</c-> <c- o>=</c-> <c- k>default</c-></code> need not introduce additional names and has a single, clear meaning.</p>
   <h3 class="heading settled" data-level="4.3" id="prior-free-template"><span class="secno">4.3. </span><span class="content">Free function template <code class="highlight"><c- k>operator</c-><c- o>++</c-><c- p>(</c-><c- n>T</c-><c- o>&amp;</c-><c- p>,</c-> <c- b>int</c-><c- p>)</c-></code></span><a class="self-link" href="#prior-free-template"></a></h3>
   <p>It would be possible to define a free function template postfix operator, which automatically generates the correct operator overloads for the class, for example:</p>
<pre class="language-cpp highlight"><c- k>template</c-><c- o>&lt;</c-><c- k>typename</c-> <c- nc>T</c-><c- o>></c-> 
<c- k>requires</c-> <c- n>std</c-><c- o>::</c-><c- n>copyable</c-><c- o>&lt;</c-><c- n>T</c-><c- o>></c-> <c- o>&amp;&amp;</c-> <c- k>requires</c-><c- p>(</c-><c- n>T</c-> <c- n>t</c-><c- p>){</c->
    <c- p>{</c-><c- o>++</c-><c- n>t</c-><c- p>}</c-> <c- o>-></c-> <c- n>std</c-><c- o>::</c-><c- n>same_as</c-><c- o>&lt;</c-><c- n>T</c-><c- o>&amp;></c-><c- p>;</c->
<c- p>}</c->
<c- k>constexpr</c-> <c- n>T</c-> <c- k>operator</c-><c- o>++</c-><c- p>(</c-><c- n>T</c-><c- o>&amp;</c-> <c- n>val</c-><c- p>,</c-> <c- b>int</c-><c- p>){</c->
    <c- n>T</c-> <c- n>copy</c-> <c- o>=</c-> <c- n>T</c-><c- p>{</c-><c- n>val</c-><c- p>};</c->
    <c- o>++</c-><c- n>val</c-><c- p>;</c->
    <c- k>return</c-> <c- n>copy</c-><c- p>;</c->
<c- p>}</c->
</pre>
   <p>This approach is opt-out, rather than opt-in, with every copyable and prefix-incrementable class automatically gaining postfix operations whether they make sense or not; and so opens the door to additional surprise features. Even if we wish to try to limit this through constraints, we cannot constrain for all possibilities. It resembles <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>rel_ops</c-></code> which never managed to be the right way to add comparison operators to an existing class and have since been deprecated.</p>
   <p>It would be possible to engineer an opt-in solution with template metaprogramming, such as some template boolean <code class="highlight"><c- n>enable_default_postfix_operations</c-></code> which the user must specialise for every class that they define. We are generally not persuaded by this solution - it has the same issue as the previous alternatives in that the user must spell what they want in an exotic way, rather than in the way provided by the language. Similarly, the potential for a class' supported basic arithmetic operators being hidden in a standard library header could be a very easy source of confusion.</p>
   <h3 class="heading settled" data-level="4.4" id="prior-P1046"><span class="secno">4.4. </span><span class="content">Automatically Generating More Operators</span><a class="self-link" href="#prior-P1046"></a></h3>
    We are not the first to propose the ability to synthesise postfix operations from prefix operators. This was previously suggested as part of <a data-link-type="biblio" href="#biblio-p1046" title="Automatically Generate More Operators">[P1046]</a>, which sought to allow the majority of C++ arithmetic operators to be automatically generated from rewrites of other operators. The author has since parked that paper in favour of a more fine-grained proposal in <a data-link-type="biblio" href="#biblio-p3039" title="Automatically Generate operator->">[P3039]</a>, which is exclusively concerned with generation of <code class="highlight"><c- k>operator</c-><c- o>-></c-><c- p>()</c-></code> and <code class="highlight"><c- k>operator</c-><c- o>->*</c-><c- p>()</c-></code>. We do not interpret this as a sign that there is no interest in automatic generation of postfix operations from their prefix counterparts, as P1046 sought to generate <code class="highlight"><c- n>x</c-><c- o>++</c-></code> implicitly, and EWG feedback was consensus in favor of explicit syntax <a data-link-type="biblio" href="#biblio-p1046-ewg" title="EWG comments from the Belfast meeting">[P1046-EWG]</a>. 
   <h2 class="heading settled" data-level="5" id="alternatives"><span class="secno">5. </span><span class="content">Alternatives Considered</span><a class="self-link" href="#alternatives"></a></h2>
   <h3 class="heading settled" data-level="5.1" id="alternative-rewrite"><span class="secno">5.1. </span><span class="content">Rewrite Rule</span><a class="self-link" href="#alternative-rewrite"></a></h3>
   <p>One alternative we considered for this change would be a rewrite rule, similar to the C++20 equality and comparison operator changes, such that <code class="highlight"><c- n>a</c-><c- o>++</c-></code> could generate a rewritten candidate equivalent to <code class="highlight"><c- p>[</c-><c- o>&amp;</c-><c- n>a</c-><c- p>]{</c-><c- k>auto</c-> <c- n>copy</c-><c- p>{</c-><c- n>a</c-><c- p>};</c-> <c- o>++</c-><c- n>a</c-><c- p>;</c-> <c- k>return</c-> <c- n>copy</c-><c- p>;}()</c-></code>. This is a subset of what was proposed in <a data-link-type="biblio" href="#biblio-p1046" title="Automatically Generate More Operators">[P1046]</a>. The benefit here was a simplification in concept - a user who wished their class to be "incrementable" need only define <code class="highlight"><c- k>operator</c-><c- o>++</c-><c- p>()</c-></code> to perform the simple increment operation and they would automatically get both operators which do the right thing. The issue with a rewrite rule is that increment and decrement operators are not as suitable for implicit operations as equality and comparison ones. The validity of <code class="highlight"><c- o>++</c-><c- n>a</c-></code> does not strictly imply validity for <code class="highlight"><c- n>a</c-><c- o>++</c-></code>, in the same way that <code class="highlight"><c- o>==</c-></code> implies that <code class="highlight"><c- o>!=</c-></code> is valid. Similarly, opt-out semantics make ill-formed code written today retroactively well-formed tomorrow, unless the author explicitly updates their library to delete functions which until now never needed to be declared.</p>
   <p>Ultimately, a rewrite rule is difficult to specify and adds additional traps to the language, so the idea was dropped.</p>
   <h3 class="heading settled" data-level="5.2" id="alternative-semantics"><span class="secno">5.2. </span><span class="content">Supporting Alternative Semantics for Postfix Increment on Iterators</span><a class="self-link" href="#alternative-semantics"></a></h3>
   <p>Some generic iterators only use the canonical semantics when the underlying iterator operates on a forward range and falls back to an alternative implementation otherwise, which only increments the underlying iterator (e.g. on <a href="https://eel.is/c++draft/move.iter.nav#3"><code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>move_iterator</c-></code></a>). We do not propose supporting this semantic as part of the defaultable semantics for postfix increment, as it creates several pitfalls:</p>
   <ul>
    <li data-md>
     <p>It is asymmetric with <code class="highlight"><c- k>operator</c-><c- o>--</c-></code>, as all ranges which support decrement are at least bidirectional.</p>
    <li data-md>
     <p>This is not the only alternative semantics for postfix increment, e.g. <a href="https://eel.is/c++draft/insert.iter.ops#7">the insert iterators</a> define it as a no-op which only exists to satisfy the requirements of <span style="font-family: monospace; font-style: italic;">LegacyOutputIterator</span>.</p>
    <li data-md>
     <p>Not every class which supports postfix increment and decrement is an iterator; so a solution would need to do nothing surprising on classes which model arithmetic types and other usages.</p>
   </ul>
   <p>It also increases rather than decreases the mental load on the developer to understand what a class does. For example, consider</p>
<pre class="language-cpp highlight"><c- k>class</c-> <c- nc>my_fun_iterator</c-><c- p>{</c->
    <c- c1>//...</c->
    <c- k>public</c-><c- o>:</c->
    <c- n>my_fun_iterator</c-><c- o>&amp;</c-> <c- k>operator</c-><c- o>++</c-><c- p>(){</c-> <c- p>...</c-> <c- p>}</c->
    <c- n>my_fun_iterator</c-> <c- k>operator</c-><c- o>++</c-><c- p>(</c-><c- b>int</c-><c- p>)</c-> <c- o>=</c-> <c- k>default</c-><c- p>;</c->
<c- p>};</c->

<c- k>class</c-> <c- nc>my_input_iterator</c-><c- p>{</c->
    <c- c1>//...</c->
    <c- k>public</c-><c- o>:</c->
    <c- n>my_input_iterator</c-><c- o>&amp;</c-> <c- k>operator</c-><c- o>++</c-><c- p>(){</c-> <c- p>...</c-> <c- p>}</c->
    <c- b>void</c-> <c- k>operator</c-><c- o>++</c-><c- p>(</c-><c- b>int</c-><c- p>)</c-> <c- o>=</c-> <c- k>default</c-><c- p>;</c->
<c- p>};</c->
</pre>
   <p>Do these two defaulted operations do the same thing? Intuitively, they should; but were we to support an "alternative" semantic we would break this intuition. The only information the user has to determine whether the defaulted operation would perform the "canonical" semantic or the "alternative" semantic is the return type of the function. Disambiguation by return type is not a path we want to walk down, as it is an entirely novel concept which has far broader implications than just getting the correct default behaviour for postfix increment.</p>
   <p>While it is good to consider common alternatives which see some consistent use, this is not the universal canonical semantic of postfix increment and we do not seek to include it in the default definition.</p>
   <h3 class="heading settled" data-level="5.3" id="alternative-templates"><span class="secno">5.3. </span><span class="content">Defaulting Templates</span><a class="self-link" href="#alternative-templates"></a></h3>
    There exists a hypothetical world where the boilerplate of defining the same postfix operator can be reduced even further. Consider this C++23 code: 
<pre class="language-cpp highlight"><c- k>class</c-> <c- nc>common_base</c-> <c- p>{</c->
    <c- b>int</c-> <c- n>m_Val</c-><c- p>{};</c->
<c- k>protected</c-><c- o>:</c->
    <c- b>int</c-> <c- n>increment</c-><c- p>()</c-> <c- p>{</c-> <c- k>return</c-> <c- o>++</c-><c- n>m_Val</c-><c- p>;</c-> <c- p>}</c->
<c- k>public</c-><c- o>:</c->
    <c- k>template</c-><c- o>&lt;</c-><c- k>typename</c-> <c- nc>Self</c-><c- o>></c->
    <c- n>Self</c-><c- o>&amp;</c-> <c- k>operator</c-><c- o>++</c-><c- p>(</c-><c- k>this</c-> <c- n>Self</c-><c- o>&amp;</c-> <c- n>self</c-><c- p>)</c-> <c- p>{</c->
        <c- n>self</c-><c- p>.</c-><c- n>increment</c-><c- p>();</c->
        <c- k>return</c-> <c- n>self</c-><c- p>;</c->
    <c- p>}</c->

    <c- k>template</c-><c- o>&lt;</c-><c- k>typename</c-> <c- nc>Self</c-><c- o>></c->
    <c- n>Self</c-> <c- k>operator</c-><c- o>++</c-><c- p>(</c-><c- k>this</c-> <c- n>Self</c-><c- o>&amp;</c-> <c- n>self</c-><c- p>,</c-> <c- b>int</c-><c- p>){</c->
        <c- k>auto</c-> <c- n>copy</c-><c- p>{</c-><c- n>self</c-><c- p>};</c->
        <c- o>++</c-><c- n>self</c-><c- p>;</c->
        <c- k>return</c-> <c- n>copy</c-><c- p>;</c->
    <c- p>}</c->

<c- p>};</c->
</pre>
   <p>If <code class="highlight"><c- n>common_base</c-></code> is the base of an extended hierarchy, then these templates will ensure that every derived class has the correct increment semantics (assuming that derived classes don’t add additional relevant state or their own increment operator overloads). As <code class="highlight"><c- o>=</c-> <c- k>default</c-></code> is just a function body which is created to be equivalent to the function body of the postfix template in that example, it would be very tempting to allow such a function template to be defaulted. However, our current specification forbids postfix operator function templates from being defaulted, as this is consistent with the other defaultable functions currently in the language.</p>
   <p>We believe that this is the sensible choice at present. While this reduction in boilerplate is desirable the implications of defaulting function templates are far broader than this example and have a different set of design questions to consider. We would prefer to see a general-purpose solution which might be extensible to other defaulted functions, and believe that such a solution should be its own paper.</p>
   <h2 class="heading settled" data-level="6" id="others"><span class="secno">6. </span><span class="content">Other Papers in this Space</span><a class="self-link" href="#others"></a></h2>
   <p>While we are not aware of any other papers seeking to automatically generate the canonical definition of postfix operators, there are some papers which are tangentially relevant because they are in a similar space. We shall examine how they may interact with this proposal.</p>
   <h3 class="heading settled" data-level="6.1" id="others-P3662"><span class="secno">6.1. </span><span class="content">P3662: Improve Increment and Decrement Operator Syntax</span><a class="self-link" href="#others-P3662"></a></h3>
   <p><a data-link-type="biblio" href="#biblio-p3662" title="Improve Increment and Decrement Operator Syntax">[P3662]</a> suggests an alternative syntax for prefix and postfix operations in order to more naturally disambiguate them, rather than use a phantom <code class="highlight"><c- b>int</c-></code>:</p>
<pre class="language-cpp highlight"><c- k>struct</c-> <c- nc>S</c-> <c- p>{</c->
  <c- k>auto</c-> <c- k>operator</c-><c- o>++</c-> <c- n>prefix</c-><c- p>()</c->  <c- p>{</c-> <c- p>...</c-> <c- p>}</c-> <c- c1>// ++s</c->
  <c- k>auto</c-> <c- k>operator</c-><c- o>++</c-> <c- n>postfix</c-><c- p>()</c-> <c- p>{</c-> <c- p>...</c-> <c- p>}</c-> <c- c1>// s++</c->
<c- p>};</c->
</pre>
   <p>With new contextual keywords <code class="highlight"><c- n>prefix</c-></code> and <code class="highlight"><c- n>postfix</c-></code>; which are token-swapped directly onto the status-quo signatures to preserve ABI. We do not believe that there is any incompatibility between this paper and P3662. As <code class="highlight"><c- k>operator</c-><c- o>++</c-> <c- n>postfix</c-><c- p>()</c-></code> maps directly onto a signature of <code class="highlight"><c- k>operator</c-><c- o>++</c-><c- p>(</c-><c- b>int</c-><c- p>)</c-></code>, we anticipate that should P3662 be accepted that no further changes would be needed for the following to be valid code.</p>
<pre class="language-cpp highlight"><c- k>struct</c-> <c- nc>S</c-> <c- p>{</c->
  <c- k>auto</c-> <c- k>operator</c-><c- o>++</c-> <c- n>prefix</c-><c- p>()</c->  <c- p>{</c-> <c- p>...</c-> <c- p>}</c->     <c- c1>// ++s</c->
  <c- n>S</c-> <c- k>operator</c-><c- o>++</c-> <c- n>postfix</c-><c- p>()</c-> <c- o>=</c-> <c- k>default</c->      <c- c1>// s++</c->
<c- p>};</c->
</pre>
   <p>We have discussed this with the author of P3662, and he agrees that there is minimal possibility of compatibility issues between the two papers. While the design of P3662 seeks to evolve following committee feedback, we would be happy to collaborate to ensure that both papers are able to progress in parallel with minimal issues.</p>
   <h3 class="heading settled" data-level="6.2" id="others-P2952"><span class="secno">6.2. </span><span class="content">P2952: auto&amp; operator=(X&amp;&amp;) = default</span><a class="self-link" href="#others-P2952"></a></h3>
   <p><a data-link-type="biblio" href="#biblio-p2952" title="auto&amp; operator=(X&amp;&amp;) = default">[P2952]</a> proposes that it should be valid to use placeholder return types in the signatures of explicitly defaulted functions, so long as those types would deduce to the correct return type for the function from the imaginary return statement in the function body. As we require that a defaulted postfix operation on class <code class="highlight"><c- n>C</c-></code> have a return type of <code class="highlight"><c- n>C</c-></code>; we specify that if the declared return type contains a placeholder type, it is deduced as if from an lvalue of type <code class="highlight"><c- n>C</c-></code>. This leads to the following behaviour:</p>
   <div class="example" id="example-f09f0339">
    <a class="self-link" href="#example-f09f0339"></a> 
    <p> The behaviour of placeholder return types for a defaulted <code class="highlight"><c- k>operator</c-><c- o>++</c-><c- p>(</c-><c- b>int</c-><c- p>)</c-></code>: </p>
<pre class="highlight"><pre class="language-cpp highlight">
<c- k><c- k>struct</c-></c-> <c- nc><c- nc>C</c-></c-><c- p><c- p>{</c-></c->
    <c- k><c- k>auto</c-></c-> <c- k><c- k>operator</c-></c-><c- o><c- o>++</c-></c-><c- p><c- p>(</c-></c-><c- b><c- b>int</c-></c-><c- p><c- p>)</c-></c-> <c- o><c- o>=</c-></c-> <c- k><c- k>default</c-></c-><c- p><c- p>;</c-></c->             <c- c1><c- c1>//Well-formed, deduces to C</c-></c->
    <c- k><c- k>decltype</c-></c-><c- p><c- p>(</c-></c-><c- k><c- k>auto</c-></c-><c- p><c- p>)</c-></c-> <c- k><c- k>operator</c-></c-><c- o><c- o>++</c-></c-><c- p><c- p>(</c-></c-><c- b><c- b>int</c-></c-><c- p><c- p>)</c-></c-> <c- o><c- o>=</c-></c-> <c- k><c- k>default</c-></c-><c- p><c- p>;</c-></c->   <c- c1><c- c1>//Well-formed, deduces to C</c-></c->
    <c- k><c- k>auto</c-></c-><c- o><c- o>*</c-></c-> <c- k><c- k>operator</c-></c-><c- o><c- o>++</c-></c-><c- p><c- p>(</c-></c-><c- b><c- b>int</c-></c-><c- p><c- p>)</c-></c-> <c- o><c- o>=</c-></c-> <c- k><c- k>default</c-></c-><c- p><c- p>;</c-></c->            <c- c1><c- c1>//Ill-formed, deduction fails</c-></c->
    <c- k><c- k>auto</c-></c-><c- o><c- o>&amp;</c-></c-> <c- k><c- k>operator</c-></c-><c- o><c- o>++</c-></c-><c- p><c- p>(</c-></c-><c- b><c- b>int</c-></c-><c- p><c- p>)</c-></c-> <c- o><c- o>=</c-></c-> <c- k><c- k>default</c-></c-><c- p><c- p>;</c-></c->            <c- c1><c- c1>//Ill-formed, C&amp; is not C</c-></c->
    <c- k><c- k>auto</c-></c-><c- o><c- o>&amp;&amp;</c-></c-> <c- k><c- k>operator</c-></c-><c- o><c- o>++</c-></c-><c- p><c- p>(</c-></c-><c- b><c- b>int</c-></c-><c- p><c- p>)</c-></c-> <c- o><c- o>=</c-></c-> <c- k><c- k>default</c-></c-><c- p><c- p>;</c-></c->           <c- c1><c- c1>//Ill-formed, C&amp; is not C</c-></c->
<c- p><c- p>};</c-></c->
</pre>
</pre>
   </div>
   <p>We anticipate no compatibility issues between the two papers. As P2952 is currently in Core for C++26, we include wording relative to it which can be used should it be accepted.</p>
   <h2 class="heading settled" data-level="7" id="existing"><span class="secno">7. </span><span class="content">Effect on Existing Code</span><a class="self-link" href="#existing"></a></h2>
    We anticipate no effects on existing code. This change is strictly additive and so only opens up possibilities for new code. 
   <h2 class="heading settled" data-level="8" id="implementation"><span class="secno">8. </span><span class="content">Implementation Experience</span><a class="self-link" href="#implementation"></a></h2>
    None yet. 
   <h2 class="heading settled" data-level="9" id="wording"><span class="secno">9. </span><span class="content">Proposed Wording</span><a class="self-link" href="#wording"></a></h2>
   <p>We tentatively propose making minimal alteration to <a href="https://eel.is/c++draft/dcl.fct.def.default">[dcl.fct.def.default]</a> and instead defining the behaviour and properties of defaulted postfix operations in a new clause [over.inc.default]. This follows the lead of the C++20 comparison changes to defaulted functions, which were largely defined in their own <a href="https://eel.is/c++draft/class.compare.default">[class.compare.default]</a> clause. We will, however, modify it to note the existence of defaulted postfix operations:</p>
   <p>Modify <strong>§9.6.2 [dcl.fct.def.default]</strong> as follows:</p>
   <blockquote>
    <p><sup>1</sup> A function definition whose <em>function-body</em> is of the form <code class="highlight"><c- o>=</c-> <c- k>default</c-></code> ; is called an <em>explicitly-defaulted definition</em>. A function that is explicitly defaulted shall </p>
    <p>
     <sup>1.1</sup>   -    be a special member function ([special]) 
     <del>or a</del>
     <ins>,</ins>
      comparison operator function ([over.binary], [class.compare.default]), 
     <ins>or postfix increment or decrement operator([over.inc.default]),</ins>
      and 
    </p>
    <p><sup>1.2</sup>   -   not have default arguments ([dcl.fct.default]). </p>
   </blockquote>
   <p>When adding the clause to define defaulted postfix operations, we note that existing wording in <a href="https://eel.is/c++draft/over.inc#2">[over.inc]</a> saves repetition by describing decrement operators as analogous to their increment counterparts. While we of course must define the behaviour of a defaulted decrement operator, we hope to use the same principle to avoid other repetition.</p>
   <p>Add clause <strong>§12.4.7.1 [over.inc.default]</strong> as follows:</p>
   <blockquote>
    <p>
     <ins><sup>1</sup> A non-template postfix increment operator function may have an <em>explicitly defaulted definition</em> ([dcl.fct.def.default]). Such a function operating on some class type <code class="highlight"><c- n>C</c-></code> shall: </ins>
    </p>
    <p>
     <ins><sup>1.1</sup>   -   be a non-static member of <code class="highlight"><c- n>C</c-></code> or a non-member function, and </ins>
    </p>
    <p>
     <ins><sup>1.2</sup>   -   be defined as defaulted in <code class="highlight"><c- n>C</c-></code> or in a context where <code class="highlight"><c- n>C</c-></code> is complete, and </ins>
    </p>
    <p>
     <ins><sup>1.3</sup>   -   have two parameters of (possibly different) type "reference to <code class="highlight"><c- n>C</c-></code>" and <code class="highlight"><c- b>int</c-></code> respectively, where the implicit object parameter (if any) is considered to be the first parameter, and </ins>
    </p>
    <p>
     <ins><sup>1.4</sup>   -   have the return type <code class="highlight"><c- n>C</c-></code>. </ins>
    </p>
    <p>
     <ins>If type <code class="highlight"><c- n>C</c-></code> does not have a declared copy constructor ([class.copy.ctor]) or prefix increment operator which is accessible from a context equivalent to the <em>function-body</em> of a defaulted postfix increment operator function, it is defined as deleted. A definition of a postfix increment operator function as defaulted that appears in a class shall be the first declaration of that function.</ins>
    </p>
    <p>
     <ins>[Example 1: </ins>
    </p>
<pre class="language-cpp highlight"><c- k>struct</c-> <c- nc>S</c-><c- p>;</c->
<c- n>S</c-> <c- k>operator</c-><c- o>++</c-><c- p>(</c-><c- n>S</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>//error: S is not complete</c->

<c- k>struct</c-> <c- nc>S</c-><c- p>{</c->
    <c- n>S</c-><c- p>(</c-><c- k>const</c-> <c- n>S</c-><c- o>&amp;</c-><c- p>)</c-> <c- o>=</c-> <c- k>default</c-><c- p>;</c->
    <c- n>S</c-><c- o>&amp;</c-> <c- k>operator</c-><c- o>++</c-><c- p>(){</c-> <c- k>return</c-> <c- o>*</c-><c- k>this</c-><c- p>;</c-> <c- p>}</c->
<c- p>};</c->
<c- n>S</c-> <c- k>operator</c-><c- o>++</c-><c- p>(</c-><c- n>S</c-><c- p>,</c-> <c- b>int</c-><c- p>)</c-> <c- o>=</c-> <c- k>default</c-><c- p>;</c->         <c- c1>//error: Incorrect parameter type</c->

<c- k>struct</c-> <c- nc>T</c-><c- p>{</c->
    <c- n>T</c-> <c- k>operator</c-><c- o>++</c-><c- p>(</c-><c- b>int</c-><c- p>)</c-> <c- o>=</c-> <c- k>default</c-><c- p>;</c->        <c- c1>//ok: Defined as deleted</c->
<c- p>};</c->

</pre>
    <p>]</p>
    <p></p>
    <p>
     <ins><sup>2</sup> A non-template postfix decrement operator function also may have an <em>explicitly-defaulted definition</em>, and is handled analogously to the postfix increment operator function.</ins>
    </p>
    <p>
     <ins><sup>3</sup> The behaviour of a defaulted postfix increment operator function operating on instance <code class="highlight"><c- n>c</c-></code> of class type <code class="highlight"><c- n>C</c-></code> shall be equivalent to: </ins>
    </p>
<pre class="language-cpp highlight"><c- n>C</c-> <c- n>tmp</c-> <c- o>=</c-> <c- n>C</c-><c- p>{</c-><c- n>c</c-><c- p>};</c->
<c- o>++</c-><c- n>c</c-><c- p>;</c->
<c- k>return</c-> <c- n>tmp</c-><c- p>;</c->
</pre>
    <p></p>
    <p>
     <ins> The behaviour of a defaulted postfix decrement operator function operating on instance <code class="highlight"><c- n>c</c-></code> of class type <code class="highlight"><c- n>C</c-></code> shall be equivalent to: </ins>
    </p>
<pre class="language-cpp highlight"><c- n>C</c-> <c- n>tmp</c-> <c- o>=</c-> <c- n>C</c-><c- p>{</c-><c- n>c</c-><c- p>};</c->
<c- o>--</c-><c- n>c</c-><c- p>;</c->
<c- k>return</c-> <c- n>tmp</c-><c- p>;</c->
</pre>
    <p></p>
   </blockquote>
   <h3 class="heading settled" data-level="9.1" id="wording-P2952"><span class="secno">9.1. </span><span class="content">Wording relative to P2952</span><a class="self-link" href="#wording-P2952"></a></h3>
   <p>If <a data-link-type="biblio" href="#biblio-p2952" title="auto&amp; operator=(X&amp;&amp;) = default">[P2952]</a> were to be accepted, we would additionally modify <strong>§12.4.7.1 [over.inc.default]</strong> as follows:</p>
   <blockquote>
    <p>
     <ins><sup>4</sup> If the declared return type of a defaulted postfix increment operator or defaulted postfix decrement operator contains a placeholder type, its return type is deduced as if from <code class="highlight"><c- k>return</c-> <c- n>r</c-></code>, where <code class="highlight"><c- n>r</c-></code> is an lvalue reference to an object of the type on which the operator is invoked.</ins>
    </p>
   </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-p1046">[P1046]
   <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>. 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-p1046-ewg">[P1046-EWG]
   <dd>EWG. <a href="https://wiki.edg.com/bin/view/Wg21belfast/P1046-EWG"><cite>EWG comments from the Belfast meeting</cite></a>. URL: <a href="https://wiki.edg.com/bin/view/Wg21belfast/P1046-EWG">https://wiki.edg.com/bin/view/Wg21belfast/P1046-EWG</a>
   <dt id="biblio-p1152">[P1152]
   <dd>JF Bastien. <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1152r4.html"><cite>Deprecating volatile</cite></a>. URL: <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1152r4.html">https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1152r4.html</a>
   <dt id="biblio-p2727">[P2727]
   <dd>Zach Laine. <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2727r4.html"><cite>std::iterator_interface</cite></a>. URL: <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2727r4.html">https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2727r4.html</a>
   <dt id="biblio-p2952">[P2952]
   <dd>Arthur O'Dwyer, Matthew Taylor. <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2025/p2952r2.html"><cite>auto&amp; operator=(X&amp;&amp;) = default</cite></a>. URL: <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2025/p2952r2.html">https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2025/p2952r2.html</a>
   <dt id="biblio-p3039">[P3039]
   <dd>David Stone. <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p3039r0.html"><cite>Automatically Generate operator-></cite></a>. URL: <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p3039r0.html">https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p3039r0.html</a>
   <dt id="biblio-p3294">[P3294]
   <dd>Andrei Alexandrescu; Barry Revzin; Daveed Vandevoorde. <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p3294r2.html"><cite>Code Injection with Token Sequences</cite></a>. URL: <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p3294r2.html">https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p3294r2.html</a>
   <dt id="biblio-p3662">[P3662]
   <dd>Jeremy Rifkin. <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3662r0.html"><cite>Improve Increment and Decrement Operator Syntax</cite></a>. URL: <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3662r0.html">https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3662r0.html</a>
  </dl>