<!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>P0847R1: Deducing this</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
 *
 * 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)
 *   - .assertion  for assertions                    (div, p, span)
 *   - .advisement for loud normative statements     (div, p, strong)
 *   - .annoying-warning for spec obsoletion notices (div, aside, details)
 *
 * 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
 *
 * 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)
 *
 ******************************************************************************/

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

	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;

		/* Colors */
		color: black;
		background: white 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-width: .65rem .7rem .6rem;
		border-radius: .4rem;
		background: #1a5e9a;
		color: white;
		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;
		border-color: #c00;
	}

	/* 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: 2;
			bottom: 0; left: 0;
			margin: 0;
			min-width: 1.33em;
			border-top-right-radius: 2rem;
			box-shadow: 0 0 2px;
			font-size: 1.5em;
			color: black;
		}
		#toc-nav > a {
			display: block;
			white-space: nowrap;

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

			background: white;
			box-shadow: 0 0 2px;
			border: none;
			border-top-right-radius: 1.33em;
			background: white;
		}
		#toc-nav > #toc-jump {
			padding-bottom: 2em;
			margin-bottom: -1.9em;
		}

		#toc-nav > a:hover,
		#toc-nav > a:focus {
			background: #f8f8f8;
		}
		#toc-nav > a:not(:hover):not(:focus) {
			color: #707070;
		}

		/* 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-toggle-inline {
			vertical-align: 0.05em;
			font-size: 80%;
			color: gray;
			color: hsla(203,20%,40%,.7);
			border-style: none;
			background: transparent;
			position: relative;
		}
		#toc-toggle-inline:hover:not(:active),
		#toc-toggle-inline:focus:not(:active) {
			text-shadow: 1px 1px silver;
			top: -1px;
			left: -1px;
		}

		#toc-nav :active {
			color: #C00;
		}
	}

/** 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);
			background: inherit;
			background-color: #f7f8f9;
			z-index: 1;
			box-shadow: -.1em 0 .25em rgba(0,0,0,.1) 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);
		}
		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);
			background: inherit;
			background-color: #f7f8f9;
			z-index: 1;
			box-shadow: -.1em 0 .25em rgba(0,0,0,.1) 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);
		}

		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;
		background: transparent;
	}

	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,
	#subtitle {
		/* #subtitle 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) > hr {
		font-size: 1.5em;
		text-align: center;
		margin: 1em auto;
		height: auto;
		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;
	}

	/* Put nice boxes around each algorithm. */
	[data-algorithm]:not(.heading) {
	  padding: .5em;
	  border: thin solid #ddd; 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: medium;
	}
	dfn var {
		font-style: normal;
	}

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

	del { color: red;  text-decoration: line-through; }
	ins { color: #080; text-decoration: underline;    }

/** 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;
		page-break-inside: avoid;
		hyphens: none;
		text-transform: none;
	}
	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;
		text-decoration: none;
		border-bottom: 1px solid #707070;
		/* Need a bit of extending for it to look okay */
		padding: 0 1px 0;
		margin: 0 -1px 0;
	}
	a:visited {
		border-bottom-color: #BBB;
	}

	/* Use distinguishing colors when user is interacting with the link */
	a[href]:focus,
	a[href]:hover {
		background: #f8f8f8;
		background: rgba(75%, 75%, 75%, .25);
		border-bottom-width: 3px;
		margin-bottom: -2px;
	}
	a[href]:active {
		color: #C00;
		border-color: #C00;
	}

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

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

	img {
		border-style: none;
	}

	/* 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;
	}
	.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 {
		padding: .5em;
		border: .5em;
		border-left-style: solid;
		page-break-inside: avoid;
	}
	span.issue, span.note {
		padding: .1em .5em .15em;
		border-right-style: solid;
	}

	.issue,
	.note,
	.example,
	.advisement,
	.assertion,
	blockquote {
		margin: 1em auto;
	}
	.note  > p:first-child,
	.issue > p:first-child,
	blockquote > :first-child {
		margin-top: 0;
	}
	blockquote > :last-child {
		margin-bottom: 0;
	}

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

	blockquote {
		border-color: silver;
	}

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

	.issue {
		border-color: #E05252;
		background: #FBE9E9;
		counter-increment: issue;
		overflow: auto;
	}
	.issue::before, .issue > .marker {
		text-transform: uppercase;
		color: #AE1E1E;
		padding-right: 1em;
		text-transform: uppercase;
	}
	/* 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;
		background: #FCFAEE;
		counter-increment: example;
		overflow: auto;
		clear: both;
	}
	.example::before, .example > .marker {
		text-transform: uppercase;
		color: #827017;
		min-width: 7.5em;
		display: block;
	}
	/* 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;
		background: #E9FBE9;
		overflow: auto;
	}

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

	details.note > summary {
		display: block;
		color: hsl(120, 70%, 30%);
	}
	details.note[open] > summary {
		border-bottom: 1px silver solid;
	}

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

	.assertion {
		border-color: #AAA;
		background: #EEE;
	}

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

	.advisement {
		border-color: orange;
		border-style: none solid;
		background: #FFEECC;
	}
	strong.advisement {
		display: block;
		text-align: center;
	}
	.advisement > .marker {
		color: #B35F00;
	}

/** 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: #fdd;
		color: red;
		font-weight: bold;
		padding: .75em 1em;
		border: thick red;
		border-style: solid;
		border-radius: 1em;
	}
	.annoying-warning :last-child {
		margin-bottom: 0;
	}

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

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

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

	.def {
		padding: .5em 1em;
		background: #DEF;
		margin: 1.2em 0;
		border-left: 0.5em solid #8CCBF2;
	}

/******************************************************************************/
/*                                    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;
	}

	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-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;
		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;
		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-top: 0.1rem;
		/* Larger, more consistently-sized click target */
		display: block;
		/* Reverse color scheme */
		color: black;
		border-color: #3980B5;
		border-bottom-width: 3px !important;
		margin-bottom: 0px !important;
	}
	.toc a:visited {
		border-color: #054572;
	}
	.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;
		line-height: 1.1rem; /* consistent spacing */
	}

	/* 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 .secno { font-size: 85%; }
	.toc > li li li li li { font-size:   85%;    }
	.toc > li li li li li .secno { font-size: 100%; }

	/* @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 {
			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; }
		}
	/* } */

	@supports (display:grid) {
		/* 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;
		}
		#toc .content:hover {
			background: rgba(75%, 75%, 75%, .25);
			border-bottom: 3px solid #054572;
			margin-bottom: -3px;
		}
		#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 span {
			white-space: nowrap;
			color: transparent; }
		ul.index li a:hover + span,
		ul.index li a:focus + span {
			color: #707070;
		}
	}

/** 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]) {
		background: #f7f8f9;
	}

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

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

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

/******************************************************************************/
/*                                    Legacy                                  */
/******************************************************************************/

	/* This rule is inherited from past style sheets. No idea what it's for. */
	.hide { display: none }



/******************************************************************************/
/*                             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 > table {
		/* limit preferred width of table */
		max-width: 50em;
		margin-left: auto;
		margin-right: auto;
	}

	@media (min-width: 55em) {
		.overlarge {
			margin-left: calc(13px + 26.5rem - 50vw);
			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-left: calc(40em - 50vw) !important;
			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-left: 0 !important;
			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 type="text/css">
    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;
    }
  </style>
  <meta content="Bikeshed version dff342f4b23fb230b71436fb31b55f5f169715bd" name="generator">
  <link href="http://wg21.link/P0847" rel="canonical">
  <link href="https://isocpp.org/favicon.ico" rel="icon">
  <meta content="633b96c0127fb83e81e06fd1a0ea6853d7efda09" name="document-revision">
<style>
.ins, ins, ins *, span.ins, span.ins * {
  background-color: rgb(200, 250, 200);
  color: rgb(0, 136, 0);
  text-decoration: none;
}

.del, del, del *, span.del, span.del * {
  background-color: rgb(250, 200, 200);
  color: rgb(255, 0, 0);
  text-decoration: line-through;
  text-decoration-color: rgb(255, 0, 0);
}
</style>
<style>/* 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>/* 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>/* style-syntax-highlighting */

.highlight:not(.idl) { background: hsl(24, 20%, 95%); }
code.highlight { padding: .1em; border-radius: .3em; }
pre.highlight, pre > code.highlight { display: block; padding: 1em; margin: .5em 0; overflow: auto; border-radius: 0; }
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 */
</style>
<style>/* style-selflinks */

.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%;
}
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: gray;
    color: white;
    font-style: normal;
    transition: opacity .2s, background-color .2s, color .2s;
}
dfn:hover > a.self-link {
    opacity: 1;
}
dfn > a.self-link:hover {
    color: black;
}

a.self-link::before            { content: "¶"; }
.heading > a.self-link::before { content: "§"; }
dfn > a.self-link::before      { content: "#"; }</style>
<style>/* style-autolinks */

.css.css, .property.property, .descriptor.descriptor {
    color: #005a9c;
    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;
}</style>
 <body class="h-entry">
  <div class="head">
   <p data-fill-with="logo"></p>
   <h1 class="p-name no-ref" id="title">P0847R1<br>Deducing this</h1>
   <h2 class="no-num no-toc no-ref heading settled" id="subtitle"><span class="content">Published Proposal, <time class="dt-updated" datetime="2018-10-07">2018-10-07</time></span></h2>
   <div data-fill-with="spec-metadata">
    <dl>
     <dt>This version:
     <dd><a class="u-url" href="http://wg21.link/P0847">http://wg21.link/P0847</a>
     <dt>Authors:
     <dd>
      <dd class="editor p-author h-card vcard"><span class="p-name fn">Gašper Ažman</span> (<span class="p-org org">gasper dot azman at gmail dot com</span>)
     <dd>
      <dd class="editor p-author h-card vcard"><span class="p-name fn">Simon Brand</span> (<span class="p-org org">simon dot brand at microsoft dot com</span>)
     <dd>
      <dd class="editor p-author h-card vcard"><span class="p-name fn">Ben Deane</span> (<span class="p-org org">ben at elbeno dot com</span>)
     <dd>
      <dd class="editor p-author h-card vcard"><span class="p-name fn">Barry Revzin</span> (<span class="p-org org">barry dot revzin at gmail dot com</span>)
     <dt>Audience:
     <dd>EWG
     <dt>Project:
     <dd>ISO/IEC JTC1/SC22/WG21 14882: Programming Language — C++
    </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>We propose a new mechanism for specifying or deducing the value category of an instance of a class — in other words, a way to tell from within a member function whether the object it’s invoked on is an lvalue or an rvalue; whether it is const or volatile; and the object’s type.</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="#changes-since-r0"><span class="secno">1.1</span> <span class="content">Changes since r0</span></a>
     </ol>
    <li><a href="#motivation"><span class="secno">2</span> <span class="content">Motivation</span></a>
    <li>
     <a href="#proposal"><span class="secno">3</span> <span class="content">Proposal</span></a>
     <ol class="toc">
      <li>
       <a href="#proposed-syntaxes"><span class="secno">3.1</span> <span class="content">Proposed Syntaxes</span></a>
       <ol class="toc">
        <li>
         <a href="#syntax-1"><span class="secno">3.1.1</span> <span class="content">Explicit <code class="highlight"><c- k>this</c-></code>-annotated parameter</span></a>
         <ol class="toc">
          <li><a href="#syntax-1-lambda"><span class="secno">3.1.1.1</span> <span class="content">Lambda version</span></a>
         </ol>
        <li>
         <a href="#syntax-2"><span class="secno">3.1.2</span> <span class="content">Explicit <code class="highlight"><c- k>this</c-></code> parameter</span></a>
         <ol class="toc">
          <li><a href="#syntax-2-lambda"><span class="secno">3.1.2.1</span> <span class="content">Lambda version</span></a>
         </ol>
        <li>
         <a href="#syntax-3"><span class="secno">3.1.3</span> <span class="content">Trailing type with identifier</span></a>
         <ol class="toc">
          <li><a href="#syntax-3-lambda"><span class="secno">3.1.3.1</span> <span class="content">Lambda version</span></a>
         </ol>
        <li>
         <a href="#syntax-4"><span class="secno">3.1.4</span> <span class="content">Trailing type sans identifier</span></a>
         <ol class="toc">
          <li><a href="#syntax-4-lambda"><span class="secno">3.1.4.1</span> <span class="content">Lambda version</span></a>
         </ol>
        <li><a href="#quick-comparison"><span class="secno">3.1.5</span> <span class="content">Quick comparison</span></a>
       </ol>
      <li>
       <a href="#proposed-semantics"><span class="secno">3.2</span> <span class="content">Proposed semantics</span></a>
       <ol class="toc">
        <li><a href="#name-lookup-candidate-functions"><span class="secno">3.2.1</span> <span class="content">Name lookup: candidate functions</span></a>
        <li><a href="#type-deduction"><span class="secno">3.2.2</span> <span class="content">Type deduction</span></a>
        <li>
         <a href="#by-value-this"><span class="secno">3.2.3</span> <span class="content">By value <code class="highlight"><c- k>this</c-></code></span></a>
         <ol class="toc">
          <li><a href="#by-value-this-explicit"><span class="secno">3.2.3.1</span> <span class="content">By value <code class="highlight"><c- k>this</c-></code> in explicit syntaxes</span></a>
          <li><a href="#by-value-this-trailing"><span class="secno">3.2.3.2</span> <span class="content">By value <code class="highlight"><c- k>this</c-></code> in trailing syntaxes</span></a>
         </ol>
        <li><a href="#name-lookup-within-member-functions"><span class="secno">3.2.4</span> <span class="content">Name lookup: within member functions</span></a>
        <li><a href="#writing-function-pointer-types"><span class="secno">3.2.5</span> <span class="content">Writing the function pointer types for such functions</span></a>
        <li><a href="#pathological-cases"><span class="secno">3.2.6</span> <span class="content">Pathological cases</span></a>
        <li><a href="#teachability-implications"><span class="secno">3.2.7</span> <span class="content">Teachability Implications</span></a>
        <li><a href="#static-member-functions"><span class="secno">3.2.8</span> <span class="content">Can <code class="highlight"><c- k>static</c-></code> member functions have an explicit object type?</span></a>
        <li>
         <a href="#interplays-with-capturing-this"><span class="secno">3.2.9</span> <span class="content">Interplays with capturing <code class="highlight"><c- p>[</c-><c- k>this</c-><c- p>]</c-></code> and <code class="highlight"><c- p>[</c-><c- o>*</c-><c- k>this</c-><c- p>]</c-></code> in lambdas</span></a>
         <ol class="toc">
          <li><a href="#capture-this-with-id"><span class="secno">3.2.9.1</span> <span class="content">Syntaxes with an identifier</span></a>
          <li><a href="#capture-this-no-id"><span class="secno">3.2.9.2</span> <span class="content">Syntaxes without an identifier</span></a>
         </ol>
        <li><a href="#parsing-issues"><span class="secno">3.2.10</span> <span class="content">Parsing issues</span></a>
       </ol>
      <li>
       <a href="#comparison"><span class="secno">3.3</span> <span class="content">Comparison of the options</span></a>
       <ol class="toc">
        <li><a href="#use-case-table"><span class="secno">3.3.1</span> <span class="content">Use-case analysis</span></a>
       </ol>
      <li><a href="#potential-extensions"><span class="secno">3.4</span> <span class="content">Potential Extension</span></a>
     </ol>
    <li>
     <a href="#real-world-examples"><span class="secno">4</span> <span class="content">Real-World Examples</span></a>
     <ol class="toc">
      <li><a href="#deduplicating-code"><span class="secno">4.1</span> <span class="content">Deduplicating Code</span></a>
      <li>
       <a href="#crtp"><span class="secno">4.2</span> <span class="content">CRTP, without the C, R, or even T</span></a>
       <ol class="toc">
        <li><a href="#builder-pattern"><span class="secno">4.2.1</span> <span class="content">Builder pattern</span></a>
       </ol>
      <li><a href="#recursive-lambdas"><span class="secno">4.3</span> <span class="content">Recursive Lambdas</span></a>
      <li>
       <a href="#by-value-member-functions"><span class="secno">4.4</span> <span class="content">By-value member functions</span></a>
       <ol class="toc">
        <li><a href="#move-into-parameter"><span class="secno">4.4.1</span> <span class="content">For move-into-parameter chaining</span></a>
        <li><a href="#by-value-member-functions-for-performance"><span class="secno">4.4.2</span> <span class="content">For performance</span></a>
       </ol>
      <li><a href="#sfinae-friendly-callables"><span class="secno">4.5</span> <span class="content">SFINAE-friendly callables</span></a>
     </ol>
    <li><a href="#suggested-polls"><span class="secno">5</span> <span class="content">Suggested Polls</span></a>
    <li><a href="#acknowledgements"><span class="secno">6</span> <span class="content">Acknowledgements</span></a>
    <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="changes-since-r0"><span class="secno">1.1. </span><span class="content">Changes since r0</span><a class="self-link" href="#changes-since-r0"></a></h3>
   <p><a data-link-type="biblio" href="#biblio-p0847r0">[P0847R0]</a> was presented in Rapperswil in June 2018 using a syntax adjusted from the one used in that paper, using <code class="highlight"><c- k>this</c-> <c- n>Self</c-><c- o>&amp;&amp;</c-> <c- n>self</c-></code> to indicate the explicit object parameter rather than the <code class="highlight"><c- n>Self</c-><c- o>&amp;&amp;</c-> <c- k>this</c-> <c- n>self</c-></code> that appeared in r0 of our paper.</p>
   <p>EWG strongly encouraged us to look in two new directions:</p>
   <ul>
    <li data-md>
     <p>a different syntax, placing the object parameter’s type after the member function’s parameter declarations (where the <em>cv-ref</em> qualifiers are today)</p>
    <li data-md>
     <p>a different name lookup scheme, which could prevent implicit/unqualified access from within new-style member functions that have an explicit self-type annotation, regardless of syntax.</p>
   </ul>
   <p>This revision carefully explores both of these directions, presents different syntaxes and lookup schemes, and discusses in depth multiple use cases and how each syntax can or cannot address them.</p>
   <h2 class="heading settled" data-level="2" id="motivation"><span class="secno">2. </span><span class="content">Motivation</span><a class="self-link" href="#motivation"></a></h2>
   <p>In C++03, member functions could have <em>cv</em>-qualifications, so it was possible to have scenarios where a particular class would want both a <code class="highlight"><c- k>const</c-></code> and non-<code class="highlight"><c- k>const</c-></code> overload of a particular member. (Note that it was also possible to want <code class="highlight"><c- k>volatile</c-></code> overloads, but those are less common and thus are not examined here.) In these cases, both overloads do the same thing — the only difference is in the types being accessed and used. This was handled by either duplicating the function while adjusting types and qualifications as necessary, or having one overload delegate to the other. An example of the latter can be found in Scott Meyers’s "Effective C++" <a data-link-type="biblio" href="#biblio-effective">[Effective]</a>, Item 3:</p>
<pre class="language-c++ highlight"><c- n>class</c-> <c- n>TextBlock</c-> <c- p>{</c->
<c- nl>public</c-><c- p>:</c->
  <c- b>char</c-> <c- k>const</c-><c- o>&amp;</c-> <c- n>operator</c-><c- p>[](</c-><c- b>size_t</c-> <c- n>position</c-><c- p>)</c-> <c- k>const</c-> <c- p>{</c->
    <c- c1>// ...</c->
    <c- k>return</c-> <c- n>text</c-><c- p>[</c-><c- n>position</c-><c- p>];</c->
  <c- p>}</c->

  <c- b>char</c-><c- o>&amp;</c-> <c- n>operator</c-><c- p>[](</c-><c- b>size_t</c-> <c- n>position</c-><c- p>)</c-> <c- p>{</c->
    <c- k>return</c-> <c- n>const_cast</c-><c- o>&lt;</c-><c- b>char</c-><c- o>&amp;></c-><c- p>(</c->
      <c- n>static_cast</c-><c- o>&lt;</c-><c- n>TextBlock</c-> <c- k>const</c-><c- o>&amp;></c-><c- p>(</c-><c- o>*</c-><c- n>this</c-><c- p>)[</c-><c- n>position</c-><c- p>]</c->
    <c- p>);</c->
  <c- p>}</c->
  <c- c1>// ...</c->
<c- p>};</c->
</pre>
   <p>Arguably, neither duplication nor delegation via <code class="highlight"><c- k>const_cast</c-></code> are great solutions, but they work.</p>
   <p>In C++11, member functions acquired a new axis to specialize on: ref-qualifiers. Now, instead of potentially needing two overloads of a single member function, we might need four: <code class="highlight"><c- o>&amp;</c-></code>, <code class="highlight"><c- k>const</c-><c- o>&amp;</c-></code>, <code class="highlight"><c- o>&amp;&amp;</c-></code>, or <code class="highlight"><c- k>const</c-><c- o>&amp;&amp;</c-></code>. We have three approaches to deal with this:</p>
   <ul>
    <li data-md>
     <p>We implement the same member four times;</p>
    <li data-md>
     <p>We have three overloads delegate to the fourth; or</p>
    <li data-md>
     <p>We have all four overloads delegate to a helper in the form of a private static member function.</p>
   </ul>
   <p>One example of the latter might be the overload set for <code class="highlight"><c- n>optional</c-><c- o>&lt;</c-><c- n>T</c-><c- o>>::</c-><c- n>value</c-><c- p>()</c-></code>, implemented as:</p>
   <table style="width:100%">
    <tbody>
     <tr>
      <th style="width:33%"> Quadruplication 
      <th style="width:33%"> Delegation to 4th 
      <th style="width:33%"> Delegation to helper 
     <tr>
      <td>
<pre class="language-cpp highlight"><c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-> <c- n>T</c-><c- o>></c->
<c- k>class</c-> <c- nc>optional</c-> <c- p>{</c->
  <c- c1>// ...</c->
  <c- k>constexpr</c-> <c- n>T</c-><c- o>&amp;</c-> <c- n>value</c-><c- p>()</c-> <c- o>&amp;</c-> <c- p>{</c->
    <c- k>if</c-> <c- p>(</c-><c- n>has_value</c-><c- p>())</c-> <c- p>{</c->
      <c- k>return</c-> <c- k>this</c-><c- o>-></c-><c- n>m_value</c-><c- p>;</c->
    <c- p>}</c->
    <c- k>throw</c-> <c- n>bad_optional_access</c-><c- p>();</c->
  <c- p>}</c->

  <c- k>constexpr</c-> <c- n>T</c-> <c- k>const</c-><c- o>&amp;</c-> <c- n>value</c-><c- p>()</c-> <c- k>const</c-><c- o>&amp;</c-> <c- p>{</c->
    <c- k>if</c-> <c- p>(</c-><c- n>has_value</c-><c- p>())</c-> <c- p>{</c->
      <c- k>return</c-> <c- k>this</c-><c- o>-></c-><c- n>m_value</c-><c- p>;</c->
    <c- p>}</c->
    <c- k>throw</c-> <c- n>bad_optional_access</c-><c- p>();</c->
  <c- p>}</c->

  <c- k>constexpr</c-> <c- n>T</c-><c- o>&amp;&amp;</c-> <c- n>value</c-><c- p>()</c-> <c- o>&amp;&amp;</c-> <c- p>{</c->
    <c- k>if</c-> <c- p>(</c-><c- n>has_value</c-><c- p>())</c-> <c- p>{</c->
      <c- k>return</c-> <c- n>move</c-><c- p>(</c-><c- k>this</c-><c- o>-></c-><c- n>m_value</c-><c- p>);</c->
    <c- p>}</c->
    <c- k>throw</c-> <c- n>bad_optional_access</c-><c- p>();</c->
  <c- p>}</c->

  <c- k>constexpr</c-> <c- n>T</c-> <c- k>const</c-><c- o>&amp;&amp;</c->
  <c- n>value</c-><c- p>()</c-> <c- k>const</c-><c- o>&amp;&amp;</c-> <c- p>{</c->
    <c- k>if</c-> <c- p>(</c-><c- n>has_value</c-><c- p>())</c-> <c- p>{</c->
      <c- k>return</c-> <c- n>move</c-><c- p>(</c-><c- k>this</c-><c- o>-></c-><c- n>m_value</c-><c- p>);</c->
    <c- p>}</c->
    <c- k>throw</c-> <c- n>bad_optional_access</c-><c- p>();</c->
  <c- p>}</c->
  <c- c1>// ...</c->
<c- p>};</c->
</pre>
      <td>
<pre class="language-cpp highlight"><c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-> <c- n>T</c-><c- o>></c->
<c- k>class</c-> <c- nc>optional</c-> <c- p>{</c->
  <c- c1>// ...</c->
  <c- k>constexpr</c-> <c- n>T</c-><c- o>&amp;</c-> <c- n>value</c-><c- p>()</c-> <c- o>&amp;</c-> <c- p>{</c->
    <c- k>return</c-> <c- k>const_cast</c-><c- o>&lt;</c-><c- n>T</c-><c- o>&amp;></c-><c- p>(</c->
      <c- k>static_cast</c-><c- o>&lt;</c-><c- n>optional</c-> <c- k>const</c-><c- o>&amp;></c-><c- p>(</c->
        <c- o>*</c-><c- k>this</c-><c- p>).</c-><c- n>value</c-><c- p>());</c->
  <c- p>}</c->

  <c- k>constexpr</c-> <c- n>T</c-> <c- k>const</c-><c- o>&amp;</c-> <c- n>value</c-><c- p>()</c-> <c- k>const</c-><c- o>&amp;</c-> <c- p>{</c->
    <c- k>if</c-> <c- p>(</c-><c- n>has_value</c-><c- p>())</c-> <c- p>{</c->
      <c- k>return</c-> <c- k>this</c-><c- o>-></c-><c- n>m_value</c-><c- p>;</c->
    <c- p>}</c->
    <c- k>throw</c-> <c- n>bad_optional_access</c-><c- p>();</c->
  <c- p>}</c->

  <c- k>constexpr</c-> <c- n>T</c-><c- o>&amp;&amp;</c-> <c- n>value</c-><c- p>()</c-> <c- o>&amp;&amp;</c-> <c- p>{</c->
    <c- k>return</c-> <c- k>const_cast</c-><c- o>&lt;</c-><c- n>T</c-><c- o>&amp;&amp;></c-><c- p>(</c->
      <c- k>static_cast</c-><c- o>&lt;</c-><c- n>optional</c-> <c- k>const</c-><c- o>&amp;></c-><c- p>(</c->
        <c- o>*</c-><c- k>this</c-><c- p>).</c-><c- n>value</c-><c- p>());</c->
  <c- p>}</c->

  <c- k>constexpr</c-> <c- n>T</c-> <c- k>const</c-><c- o>&amp;&amp;</c->
  <c- n>value</c-><c- p>()</c-> <c- k>const</c-><c- o>&amp;&amp;</c-> <c- p>{</c->
    <c- k>return</c-> <c- k>static_cast</c-><c- o>&lt;</c-><c- n>T</c-> <c- k>const</c-><c- o>&amp;&amp;></c-><c- p>(</c->
      <c- n>value</c-><c- p>());</c->
  <c- p>}</c->
  <c- c1>// ...</c->
<c- p>};</c->
</pre>
      <td>
<pre class="language-cpp highlight"><c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-> <c- n>T</c-><c- o>></c->
<c- k>class</c-> <c- nc>optional</c-> <c- p>{</c->
  <c- c1>// ...</c->
  <c- k>constexpr</c-> <c- n>T</c-><c- o>&amp;</c-> <c- n>value</c-><c- p>()</c-> <c- o>&amp;</c-> <c- p>{</c->
    <c- k>return</c-> <c- n>value_impl</c-><c- p>(</c-><c- o>*</c-><c- k>this</c-><c- p>);</c->
  <c- p>}</c->

  <c- k>constexpr</c-> <c- n>T</c-> <c- k>const</c-><c- o>&amp;</c-> <c- n>value</c-><c- p>()</c-> <c- k>const</c-><c- o>&amp;</c-> <c- p>{</c->
    <c- k>return</c-> <c- n>value_impl</c-><c- p>(</c-><c- o>*</c-><c- k>this</c-><c- p>);</c->
  <c- p>}</c->

  <c- k>constexpr</c-> <c- n>T</c-><c- o>&amp;&amp;</c-> <c- n>value</c-><c- p>()</c-> <c- o>&amp;&amp;</c-> <c- p>{</c->
    <c- k>return</c-> <c- n>value_impl</c-><c- p>(</c-><c- n>move</c-><c- p>(</c-><c- o>*</c-><c- k>this</c-><c- p>));</c->
  <c- p>}</c->

  <c- k>constexpr</c-> <c- n>T</c-> <c- k>const</c-><c- o>&amp;&amp;</c->
  <c- n>value</c-><c- p>()</c-> <c- k>const</c-><c- o>&amp;&amp;</c-> <c- p>{</c->
    <c- k>return</c-> <c- n>value_impl</c-><c- p>(</c-><c- n>move</c-><c- p>(</c-><c- o>*</c-><c- k>this</c-><c- p>));</c->
  <c- p>}</c->

<c- k>private</c-><c- o>:</c->
  <c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-> <c- n>Opt</c-><c- o>></c->
  <c- k>static</c-> <c- k>decltype</c-><c- p>(</c-><c- k>auto</c-><c- p>)</c->
  <c- n>value_impl</c-><c- p>(</c-><c- n>Opt</c-><c- o>&amp;&amp;</c-> <c- n>opt</c-><c- p>)</c-> <c- p>{</c->
    <c- k>if</c-> <c- p>(</c-><c- o>!</c-><c- n>opt</c-><c- p>.</c-><c- n>has_value</c-><c- p>())</c-> <c- p>{</c->
      <c- k>throw</c-> <c- n>bad_optional_access</c-><c- p>();</c->
    <c- p>}</c->
    <c- k>return</c-> <c- n>forward</c-><c- o>&lt;</c-><c- n>Opt</c-><c- o>></c-><c- p>(</c-><c- n>opt</c-><c- p>).</c-><c- n>m_value</c-><c- p>;</c->
  <c- p>}</c->
  <c- c1>// ...</c->
<c- p>};</c->
</pre>
   </table>
   <p>This is far from a complicated function, but essentially repeating the same code four times — or using artificial delegation to avoid doing so — begs a rewrite. Unfortunately, it’s impossible to improve; we <em>must</em> implement it this way. It seems we should be able to abstract away the qualifiers as we can for non-member functions, where we simply don’t have this problem:</p>
<pre class="language-cpp highlight"><c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-> <c- n>T</c-><c- o>></c->
<c- k>class</c-> <c- nc>optional</c-> <c- p>{</c->
    <c- c1>// ...</c->
    <c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-> <c- n>Opt</c-><c- o>></c->
    <c- k>friend</c-> <c- k>decltype</c-><c- p>(</c-><c- k>auto</c-><c- p>)</c-> <c- n>value</c-><c- p>(</c-><c- n>Opt</c-><c- o>&amp;&amp;</c-> <c- n>o</c-><c- p>)</c-> <c- p>{</c->
        <c- k>if</c-> <c- p>(</c-><c- n>o</c-><c- p>.</c-><c- n>has_value</c-><c- p>())</c-> <c- p>{</c->
            <c- k>return</c-> <c- n>forward</c-><c- o>&lt;</c-><c- n>Opt</c-><c- o>></c-><c- p>(</c-><c- n>o</c-><c- p>).</c-><c- n>m_value</c-><c- p>;</c->
        <c- p>}</c->
        <c- k>throw</c-> <c- n>bad_optional_access</c-><c- p>();</c->
    <c- p>}</c->
    <c- c1>// ...</c->
<c- p>};</c->
</pre>
   <p>All four cases are now handled with just one function... except it’s a non-member function, not a member function. Different semantics, different syntax, doesn’t help.</p>
   <p>There are many cases where we need two or four overloads of the same member function for different <code class="highlight"><c- k>const</c-></code>- or ref-qualifiers. More than that, there are likely additional cases where a class should have four overloads of a particular member function but, due to developer laziness, doesn’t. We think that there are enough such cases to merit a better solution than simply "write it, write it again, then write it two more times."</p>
   <h2 class="heading settled" data-level="3" id="proposal"><span class="secno">3. </span><span class="content">Proposal</span><a class="self-link" href="#proposal"></a></h2>
   <p>We propose a new way of declaring non-static member functions that will allow for deducing the type and value category of the class instance parameter while still being invocable with regular member function syntax.</p>
   <p>We believe that the ability to write <em>cv-ref qualifier</em>-aware member function templates without duplication will improve code maintainability, decrease the likelihood of bugs, and make fast, correct code easier to write.</p>
   <p>The proposal is sufficiently general and orthogonal to allow for several new exciting features and design patterns for C++:</p>
   <ul>
    <li data-md>
     <p><a href="#recursive-lambdas">recursive lambdas</a></p>
    <li data-md>
     <p>a new approach to <a href="#crtp">mixins</a>, a CRTP without the CRT</p>
    <li data-md>
     <p><a href="#move-into-parameter">move-or-copy-into-parameter support for member functions</a></p>
    <li data-md>
     <p>efficiency by avoiding double indirection with <a href="#by-value-member-functions-for-performance">invocation</a></p>
    <li data-md>
     <p>perfect, sfinae-friendly <a href="#sfinae-friendly-callables">call wrappers</a></p>
   </ul>
   <p>These are explored in detail in the <a href="#real-world-examples">examples</a> section.</p>
   <p>This proposal assumes the existence of two library additions, though it does not propose them:</p>
   <ul>
    <li data-md>
     <p><code class="highlight"><c- n>like_t</c-></code>, a metafunction that applies the <em>cv</em>- and <em>ref</em>-qualifiers of the first type onto the second (e.g. <code class="highlight"><c- n>like_t</c-><c- o>&lt;</c-><c- b>int</c-><c- o>&amp;</c-><c- p>,</c-> <c- b>double</c-><c- o>></c-></code> is <code class="highlight"><c- b>double</c-><c- o>&amp;</c-></code>, <code class="highlight"><c- n>like_t</c-><c- o>&lt;</c-><c- n>X</c-> <c- k>const</c-><c- o>&amp;&amp;</c-><c- p>,</c-> <c- n>Y</c-><c- o>></c-></code> is <code class="highlight"><c- n>Y</c-> <c- k>const</c-><c- o>&amp;&amp;</c-></code>, etc.)</p>
    <li data-md>
     <p><code class="highlight"><c- n>forward_like</c-></code>, a version of <code class="highlight"><c- n>forward</c-></code> that is intended to forward a variable not based on its own type but instead based on some other type. <code class="highlight"><c- n>forward_like</c-><c- o>&lt;</c-><c- n>T</c-><c- o>></c-><c- p>(</c-><c- n>u</c-><c- p>)</c-></code> is short-hand for <code class="highlight"><c- n>forward</c-><c- o>&lt;</c-><c- n>like_t</c-><c- o>&lt;</c-><c- n>T</c-><c- p>,</c-><c- k>decltype</c-><c- p>(</c-><c- n>u</c-><c- p>)</c-><c- o>>></c-><c- p>(</c-><c- n>u</c-><c- p>)</c-></code>.</p>
   </ul>
   <h3 class="heading settled" data-level="3.1" id="proposed-syntaxes"><span class="secno">3.1. </span><span class="content">Proposed Syntaxes</span><a class="self-link" href="#proposed-syntaxes"></a></h3>
   <p>There are four syntax options for solving this problem which will be used throughout the examples in the rest of our proposal; this section briefly introduces those options. Semantics are more thoroughly explained in later sections. The various syntaxes used imply subtly different semantics which are called out where relevant. This paper takes the position that only one option be chosen, depending on the desired characteristics.</p>
   <h4 class="heading settled" data-level="3.1.1" id="syntax-1"><span class="secno">3.1.1. </span><span class="content">Explicit <code class="highlight"><c- k>this</c-></code>-annotated parameter</span><a class="self-link" href="#syntax-1"></a></h4>
   <p>A non-static member function can be declared to take as its first parameter an <em>explicit object parameter</em>, denoted with the prefixed keyword <code class="highlight"><c- k>this</c-></code>. Once we elevate the object parameter to a proper function parameter, it can be deduced following normal function template deduction rules:</p>
<pre class="language-cpp highlight"><c- k>struct</c-> <c- n>X</c-> <c- p>{</c->
    <c- b>void</c-> <c- n>foo</c-><c- p>(</c-><c- k>this</c-> <c- n>X</c-> <c- k>const</c-><c- o>&amp;</c-> <c- n>self</c-><c- p>,</c-> <c- b>int</c-> <c- n>i</c-><c- p>);</c->
    
    <c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-> <c- n>Self</c-><c- o>></c->
    <c- b>void</c-> <c- n>bar</c-><c- p>(</c-><c- k>this</c-> <c- n>Self</c-><c- o>&amp;&amp;</c-> <c- n>self</c-><c- p>);</c->
<c- p>};</c->

<c- k>struct</c-> <c- nl>D</c-> <c- p>:</c-> <c- n>X</c-> <c- p>{</c-> <c- p>};</c->

<c- b>void</c-> <c- nf>ex</c-><c- p>(</c-><c- n>X</c-><c- o>&amp;</c-> <c- n>x</c-><c- p>,</c-> <c- n>D</c-> <c- k>const</c-><c- o>&amp;</c-> <c- n>d</c-><c- p>)</c-> <c- p>{</c->
    <c- n>x</c-><c- p>.</c-><c- n>foo</c-><c- p>(</c-><c- mi>42</c-><c- p>);</c->      <c- c1>// 'self' is bound to 'x', 'i' is 42</c->
    <c- n>x</c-><c- p>.</c-><c- n>bar</c-><c- p>();</c->        <c- c1>// deduces Self as X&amp;, calls X::bar&lt;X&amp;></c->
    <c- n>move</c-><c- p>(</c-><c- n>x</c-><c- p>).</c-><c- n>bar</c-><c- p>();</c->  <c- c1>// deduces Self as X, calls X::bar&lt;X></c->
    
    <c- n>d</c-><c- p>.</c-><c- n>foo</c-><c- p>(</c-><c- mi>17</c-><c- p>);</c->      <c- c1>// 'self' is bound to 'd'</c->
    <c- n>d</c-><c- p>.</c-><c- n>bar</c-><c- p>();</c->        <c- c1>// deduces Self as D const&amp;, calls X::bar&lt;D const&amp;></c->
<c- p>}</c->
</pre>
   <p>Member functions with an explicit object parameter cannot be <code class="highlight"><c- k>static</c-></code> or have <em>cv</em>- or <em>ref</em>-qualifiers.</p>
   <p>A call to a member function will interpret the object argument as the first (<code class="highlight"><c- k>this</c-></code>-annotated) parameter to it; the first argument in the parenthesized expression list is then interpreted as the second parameter, and so forth.</p>
   <p>Following normal deduction rules, the template parameter corresponding to the explicit object parameter can deduce to a type derived from the class in which the member function is declared, as in the example above for <code class="highlight"><c- n>d</c-><c- p>.</c-><c- n>bar</c-><c- p>()</c-></code>).</p>
   <h5 class="heading settled" data-level="3.1.1.1" id="syntax-1-lambda"><span class="secno">3.1.1.1. </span><span class="content">Lambda version</span><a class="self-link" href="#syntax-1-lambda"></a></h5>
   <p>The lambda version of the above, for reference:</p>
<pre class="language-cpp highlight"><c- n>vector</c-> <c- n>captured</c-> <c- o>=</c-> <c- p>{</c-><c- mi>1</c-><c- p>,</c-> <c- mi>2</c-><c- p>,</c-> <c- mi>3</c-><c- p>,</c-> <c- mi>4</c-><c- p>};</c->
<c- p>[</c-><c- n>captured</c-><c- p>](</c-><c- k>this</c-> <c- k>auto</c-><c- o>&amp;&amp;</c-> <c- n>self</c-><c- p>)</c-> <c- o>-></c-> <c- k>decltype</c-><c- p>(</c-><c- k>auto</c-><c- p>)</c-> <c- p>{</c-> 
  <c- k>return</c-> <c- n>forward_like</c-><c- o>&lt;</c-><c- k>decltype</c-><c- p>(</c-><c- n>self</c-><c- p>)</c-><c- o>></c-><c- p>(</c-><c- n>captured</c-><c- p>);</c->
<c- p>}</c->

<c- p>[</c-><c- n>captured</c-><c- p>]</c-><c- o>&lt;</c-><c- k>class</c-> <c- nc>Self</c-><c- o>></c-><c- p>(</c-><c- k>this</c-> <c- n>Self</c-><c- o>&amp;&amp;</c-> <c- n>self</c-><c- p>)</c-> <c- o>-></c-> <c- k>decltype</c-><c- p>(</c-><c- k>auto</c-><c- p>)</c-> <c- p>{</c->
  <c- k>return</c-> <c- n>forward_like</c-><c- o>&lt;</c-><c- n>Self</c-><c- o>></c-><c- p>(</c-><c- n>captured</c-><c- p>);</c->
<c- p>}</c->
</pre>
   <p>The lambdas can either move or copy from the capture, depending on whether the lambda is an lvalue or an rvalue.</p>
   <h4 class="heading settled" data-level="3.1.2" id="syntax-2"><span class="secno">3.1.2. </span><span class="content">Explicit <code class="highlight"><c- k>this</c-></code> parameter</span><a class="self-link" href="#syntax-2"></a></h4>
   <p>A non-static member function can be declared to take <code class="highlight"><c- k>this</c-></code> as its first parameter. As with <a href="#syntax-1">§3.1.1 Explicit this-annotated parameter</a>, once we elevate the object parameter to a proper function parameter, it can be deduced following normal function template deduction rules. In this case, instead of remaining a pointer, <code class="highlight"><c- k>this</c-></code> becomes a reference of the type the parameter suggested by the parameter, fixing a long-standing oversight of the language, stemming from before the invention of references.</p>
<pre class="language-cpp highlight"><c- k>struct</c-> <c- n>X</c-> <c- p>{</c->
    <c- b>void</c-> <c- n>foo</c-><c- p>(</c-><c- n>X</c-> <c- k>const</c-><c- o>&amp;</c-> <c- k>this</c-><c- p>,</c-> <c- b>int</c-> <c- n>i</c-><c- p>);</c->
    
    <c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-> <c- n>Self</c-><c- o>></c->
    <c- b>void</c-> <c- n>bar</c-><c- p>(</c-><c- n>Self</c-><c- o>&amp;&amp;</c-> <c- k>this</c-><c- p>);</c->
<c- p>};</c->

<c- k>struct</c-> <c- nl>D</c-> <c- p>:</c-> <c- n>X</c-> <c- p>{</c-> <c- p>};</c->

<c- b>void</c-> <c- nf>ex</c-><c- p>(</c-><c- n>X</c-><c- o>&amp;</c-> <c- n>x</c-><c- p>,</c-> <c- n>D</c-> <c- k>const</c-><c- o>&amp;</c-> <c- n>d</c-><c- p>)</c-> <c- p>{</c->
    <c- n>x</c-><c- p>.</c-><c- n>foo</c-><c- p>(</c-><c- mi>42</c-><c- p>);</c->      <c- c1>// 'this' is bound to 'x', 'i' is 42</c->
    <c- n>x</c-><c- p>.</c-><c- n>bar</c-><c- p>();</c->        <c- c1>// deduces Self as X&amp;, calls X::bar&lt;X&amp;></c->
    <c- n>move</c-><c- p>(</c-><c- n>x</c-><c- p>).</c-><c- n>bar</c-><c- p>();</c->  <c- c1>// deduces Self as X, calls X::bar&lt;X></c->
    
    <c- n>d</c-><c- p>.</c-><c- n>foo</c-><c- p>(</c-><c- mi>17</c-><c- p>);</c->      <c- c1>// 'this' is bound to 'd'</c->
    <c- n>d</c-><c- p>.</c-><c- n>bar</c-><c- p>();</c->        <c- c1>// deduces Self as D const&amp;, calls X::bar&lt;D const&amp;></c->
<c- p>}</c->
</pre>
   <p>As with <a href="#syntax-1">§3.1.1 Explicit this-annotated parameter</a>, member functions with an explicit object parameter cannot be <code class="highlight"><c- k>static</c-></code> or have <em>cv</em>- or <em>ref</em>-qualifiers.</p>
   <p>A call to a member function will interpret the object argument as its first <code class="highlight"><c- k>this</c-></code> parameter and the first argument in the parenthesized expression list as its second parameter (and so on).</p>
   <p>Following normal deduction rules, the template parameter corresponding to the explicit object parameter can deduce to a type derived from the class in which the member function is declared, as in the example above for <code class="highlight"><c- n>d</c-><c- p>.</c-><c- n>bar</c-><c- p>()</c-></code>.</p>
   <h5 class="heading settled" data-level="3.1.2.1" id="syntax-2-lambda"><span class="secno">3.1.2.1. </span><span class="content">Lambda version</span><a class="self-link" href="#syntax-2-lambda"></a></h5>
   <p>The lambda version of the above, for reference:</p>
<pre class="language-cpp highlight"><c- n>vector</c-> <c- n>captured</c-> <c- o>=</c-> <c- p>{</c-><c- mi>1</c-><c- p>,</c-> <c- mi>2</c-><c- p>,</c-> <c- mi>3</c-><c- p>,</c-> <c- mi>4</c-><c- p>};</c->
<c- p>[</c-><c- n>captured</c-><c- p>](</c-><c- k>auto</c-><c- o>&amp;&amp;</c-> <c- k>this</c-><c- p>)</c-> <c- o>-></c-> <c- k>decltype</c-><c- p>(</c-><c- k>auto</c-><c- p>)</c-> <c- p>{</c-> 
  <c- k>return</c-> <c- n>forward_like</c-><c- o>&lt;</c-><c- k>decltype</c-><c- p>(</c-><c- k>this</c-><c- p>)</c-><c- o>></c-><c- p>(</c-><c- n>captured</c-><c- p>);</c->
<c- p>}</c->

<c- p>[</c-><c- n>captured</c-><c- p>]</c-><c- o>&lt;</c-><c- k>class</c-> <c- nc>Self</c-><c- o>></c-><c- p>(</c-><c- n>Self</c-><c- o>&amp;&amp;</c-> <c- k>this</c-><c- p>)</c-> <c- o>-></c-> <c- k>decltype</c-><c- p>(</c-><c- k>auto</c-><c- p>)</c-> <c- p>{</c->
  <c- k>return</c-> <c- n>forward_like</c-><c- o>&lt;</c-><c- n>Self</c-><c- o>></c-><c- p>(</c-><c- n>captured</c-><c- p>);</c->
<c- p>}</c->
</pre>
   <h4 class="heading settled" data-level="3.1.3" id="syntax-3"><span class="secno">3.1.3. </span><span class="content">Trailing type with identifier</span><a class="self-link" href="#syntax-3"></a></h4>
   <p>In C++17, member functions can optionally have a <em>cv-qualifier</em> and a <em>ref-qualifier</em>. This can be extended to allow a full type and an identifier so that the trailer of the member function declaration effectively becomes a variable declaration for the object parameter:</p>
<pre class="language-cpp highlight"><c- k>struct</c-> <c- n>X</c-> <c- p>{</c->
    <c- b>void</c-> <c- n>foo</c-><c- p>(</c-><c- b>int</c-> <c- n>i</c-><c- p>)</c-> <c- n>X</c-> <c- k>const</c-><c- o>&amp;</c-> <c- n>self</c-><c- p>;</c->
    
    <c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-> <c- n>Self</c-><c- o>></c->
    <c- b>void</c-> <c- n>bar</c-><c- p>()</c-> <c- n>Self</c-><c- o>&amp;&amp;</c-> <c- n>self</c-><c- p>;</c->
<c- p>};</c-> 

<c- k>struct</c-> <c- nl>D</c-> <c- p>:</c-> <c- n>X</c-> <c- p>{</c-> <c- p>};</c->

<c- b>void</c-> <c- nf>ex</c-><c- p>(</c-><c- n>X</c-><c- o>&amp;</c-> <c- n>x</c-><c- p>,</c-> <c- n>D</c-> <c- k>const</c-><c- o>&amp;</c-> <c- n>d</c-><c- p>)</c-> <c- p>{</c->
    <c- n>x</c-><c- p>.</c-><c- n>foo</c-><c- p>(</c-><c- mi>42</c-><c- p>);</c->      <c- c1>// 'self' is bound to 'x', 'i' is 42</c->
    <c- n>x</c-><c- p>.</c-><c- n>bar</c-><c- p>();</c->        <c- c1>// deduces Self as X&amp;, calls X::bar&lt;X&amp;></c->
    <c- n>move</c-><c- p>(</c-><c- n>x</c-><c- p>).</c-><c- n>bar</c-><c- p>();</c->  <c- c1>// deduces Self as X, calls X::bar&lt;X></c->
    
    <c- n>d</c-><c- p>.</c-><c- n>foo</c-><c- p>(</c-><c- mi>17</c-><c- p>);</c->      <c- c1>// 'self' is bound to 'd'</c->
    <c- n>d</c-><c- p>.</c-><c- n>bar</c-><c- p>();</c->        <c- c1>// deduces Self as D const&amp;, calls X::bar&lt;D const&amp;></c->
<c- p>}</c->
</pre>
   <p>This takes the previously introduced <a href="#syntax-1">§3.1.1 Explicit this-annotated parameter</a> and simply declares it after the parameter declaration clause instead of at the front of it. The grammar is extended with a parameter declaration, where current-syntax member functions behave as if the class name were omitted.</p>
   <p>Member functions with an trailing object type cannot be <code class="highlight"><c- k>static</c-></code>.</p>
   <h5 class="heading settled" data-level="3.1.3.1" id="syntax-3-lambda"><span class="secno">3.1.3.1. </span><span class="content">Lambda version</span><a class="self-link" href="#syntax-3-lambda"></a></h5>
   <p>The lambda version of the above, for reference:</p>
<pre class="language-cpp highlight"><c- n>vector</c-> <c- n>captured</c-> <c- o>=</c-> <c- p>{</c-><c- mi>1</c-><c- p>,</c-> <c- mi>2</c-><c- p>,</c-> <c- mi>3</c-><c- p>,</c-> <c- mi>4</c-><c- p>};</c->
<c- p>[</c-><c- n>captured</c-><c- p>]</c-><c- o>&lt;</c-><c- k>class</c-> <c- nc>Self</c-><c- o>></c-><c- p>()</c-> <c- n>Self</c-><c- o>&amp;&amp;</c-> <c- n>self</c-> <c- o>-></c-> <c- k>decltype</c-><c- p>(</c-><c- k>auto</c-><c- p>)</c-> <c- p>{</c->
  <c- k>return</c-> <c- n>forward_like</c-><c- o>&lt;</c-><c- n>Self</c-><c- o>></c-><c- p>(</c-><c- n>captured</c-><c- p>);</c->
<c- p>}</c->
</pre>
   <p>Note that this syntax obviates <code class="highlight"><c- k>mutable</c-></code> and <code class="highlight"><c- k>const</c-></code> qualifiers for the lambda and introduces significant parsing issues due to <code class="highlight"><c- n>self</c-></code> being both completely freeform and optional.</p>
   <h4 class="heading settled" data-level="3.1.4" id="syntax-4"><span class="secno">3.1.4. </span><span class="content">Trailing type sans identifier</span><a class="self-link" href="#syntax-4"></a></h4>
   <p>Similar to the above, except without a possible identifier.</p>
<pre class="language-cpp highlight"><c- k>struct</c-> <c- n>X</c-> <c- p>{</c->
    <c- b>void</c-> <c- n>foo</c-><c- p>(</c-><c- b>int</c-> <c- n>i</c-><c- p>)</c-> <c- n>X</c-> <c- k>const</c-><c- o>&amp;</c-><c- p>;</c->
    
    <c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-> <c- n>Self</c-><c- o>></c->
    <c- b>void</c-> <c- n>bar</c-><c- p>()</c-> <c- n>Self</c-><c- o>&amp;&amp;</c-><c- p>;</c->
<c- p>};</c-> 

<c- k>struct</c-> <c- nl>D</c-> <c- p>:</c-> <c- n>X</c-> <c- p>{</c-> <c- p>};</c->

<c- b>void</c-> <c- nf>ex</c-><c- p>(</c-><c- n>X</c-><c- o>&amp;</c-> <c- n>x</c-><c- p>,</c-> <c- n>D</c-> <c- k>const</c-><c- o>&amp;</c-> <c- n>d</c-><c- p>)</c-> <c- p>{</c->
    <c- n>x</c-><c- p>.</c-><c- n>foo</c-><c- p>(</c-><c- mi>42</c-><c- p>);</c->      <c- c1>// this is a X const*</c->
    <c- n>x</c-><c- p>.</c-><c- n>bar</c-><c- p>();</c->        <c- c1>// deduces Self as X&amp;, this is a X*</c->
    <c- n>move</c-><c- p>(</c-><c- n>x</c-><c- p>).</c-><c- n>bar</c-><c- p>();</c->  <c- c1>// deduces Self as X, this is a X*</c->
    
    <c- n>d</c-><c- p>.</c-><c- n>foo</c-><c- p>(</c-><c- mi>17</c-><c- p>);</c->      <c- c1>// this is a X const*</c->
    <c- n>d</c-><c- p>.</c-><c- n>bar</c-><c- p>();</c->        <c- c1>// deduces Self as D const&amp;, this is a D const*</c->
<c- p>}</c->
</pre>
   <p>Because we need a way to refer to the derived object but are no longer introducing an identifier for it, we are forced to use <code class="highlight"><c- k>this</c-></code>. The optionality of introducing a type-identifier would suggest that <code class="highlight"><c- k>this</c-></code> not change meaning in the body of such a member function; in other words, <code class="highlight"><c- k>this</c-></code> stays a pointer to an appropriately cv-ref qualified object.</p>
   <p>Refer to <a href="#name-lookup-within-member-functions">§3.2.4 Name lookup: within member functions</a> for a discussion of the various options for handling name lookup in the member function bodies for each syntax.</p>
   <h5 class="heading settled" data-level="3.1.4.1" id="syntax-4-lambda"><span class="secno">3.1.4.1. </span><span class="content">Lambda version</span><a class="self-link" href="#syntax-4-lambda"></a></h5>
   <p>The lambda version of the above, for reference:</p>
<pre class="language-cpp highlight"><c- n>vector</c-> <c- n>captured</c-> <c- o>=</c-> <c- p>{</c-><c- mi>1</c-><c- p>,</c-> <c- mi>2</c-><c- p>,</c-> <c- mi>3</c-><c- p>,</c-> <c- mi>4</c-><c- p>};</c->
<c- p>[</c-><c- n>captured</c-><c- p>]</c-><c- o>&lt;</c-><c- k>class</c-> <c- nc>Self</c-><c- o>></c-><c- p>()</c-> <c- n>Self</c-><c- o>&amp;&amp;</c-> <c- o>-></c-> <c- k>decltype</c-><c- p>(</c-><c- k>auto</c-><c- p>)</c-> <c- p>{</c->
  <c- k>return</c-> <c- n>forward_like</c-><c- o>&lt;</c-><c- n>Self</c-><c- o>></c-><c- p>(</c-><c- n>captured</c-><c- p>);</c->
<c- p>}</c->
</pre>
   <p>One should note that this syntax obviates <code class="highlight"><c- k>mutable</c-></code> and <code class="highlight"><c- k>const</c-></code> qualifiers for the lambda.</p>
   <h4 class="heading settled" data-level="3.1.5" id="quick-comparison"><span class="secno">3.1.5. </span><span class="content">Quick comparison</span><a class="self-link" href="#quick-comparison"></a></h4>
   <p>This serves as a brief demonstration of how to write <code class="highlight"><c- n>optional</c-><c- o>::</c-><c- n>value</c-><c- p>()</c-></code> and <code class="highlight"><c- n>optional</c-><c- o>::</c-><c- k>operator</c-><c- o>-></c-><c- p>()</c-></code> in just two functions instead of six with no duplication using each of the four proposed syntaxes.</p>
   <p>There are several options as to the semantics of <code class="highlight"><c- k>this</c-></code> within member function bodies, with this quick illustrative example being the most conservative approach:</p>
   <table style="width:100%">
    <tbody>
     <tr>
      <th style="width:50%"> <a href="#syntax-1">§3.1.1 Explicit this-annotated parameter</a> 
      <th style="width:50%"> <a href="#syntax-2">§3.1.2 Explicit this parameter</a> 
     <tr>
      <td>
<pre class="language-cpp highlight"><c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-> <c- n>T</c-><c- o>></c->
<c- k>struct</c-> <c- n>optional</c-> <c- p>{</c->
  <c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-> <c- n>Self</c-><c- o>></c->
  <c- k>constexpr</c-> <c- k>auto</c-><c- o>&amp;&amp;</c-> <c- n>value</c-><c- p>(</c-><c- k>this</c-> <c- n>Self</c-><c- o>&amp;&amp;</c-> <c- n>self</c-><c- p>)</c-> <c- p>{</c->
    <c- k>if</c-> <c- p>(</c-><c- o>!</c-><c- n>self</c-><c- p>.</c-><c- n>has_value</c-><c- p>())</c-> <c- p>{</c->
      <c- k>throw</c-> <c- n>bad_optional_access</c-><c- p>();</c->
    <c- p>}</c->
        
    <c- k>return</c-> <c- n>forward</c-><c- o>&lt;</c-><c- n>Self</c-><c- o>></c-><c- p>(</c-><c- n>self</c-><c- p>).</c-><c- n>m_value</c-><c- p>;</c->
  <c- p>}</c->
    
  <c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-> <c- n>Self</c-><c- o>></c->
  <c- k>constexpr</c-> <c- k>auto</c-> <c- k>operator</c-><c- o>-></c-><c- p>(</c-><c- k>this</c-> <c- n>Self</c-><c- o>&amp;&amp;</c-> <c- n>self</c-><c- p>)</c-> <c- p>{</c->
    <c- k>return</c-> <c- n>addressof</c-><c- p>(</c-><c- n>self</c-><c- p>.</c-><c- n>m_value</c-><c- p>);</c->
  <c- p>}</c->
<c- p>};</c->
</pre>
      <td>
<pre class="language-cpp highlight"><c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-> <c- n>T</c-><c- o>></c->
<c- k>struct</c-> <c- n>optional</c-> <c- p>{</c->
  <c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-> <c- n>Self</c-><c- o>></c->
  <c- k>constexpr</c-> <c- k>auto</c-><c- o>&amp;&amp;</c-> <c- n>value</c-><c- p>(</c-><c- n>Self</c-><c- o>&amp;&amp;</c-> <c- k>this</c-><c- p>)</c-> <c- p>{</c->
    <c- k>if</c-> <c- p>(</c-><c- o>!</c-><c- k>this</c-><c- p>.</c-><c- n>has_value</c-><c- p>())</c-> <c- p>{</c->
      <c- k>throw</c-> <c- n>bad_optional_access</c-><c- p>();</c->
    <c- p>}</c->
        
    <c- k>return</c-> <c- n>forward</c-><c- o>&lt;</c-><c- n>Self</c-><c- o>></c-><c- p>(</c-><c- k>this</c-><c- p>).</c-><c- n>m_value</c-><c- p>;</c->
  <c- p>}</c->
    
  <c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-> <c- n>Self</c-><c- o>></c->
  <c- k>constexpr</c-> <c- k>auto</c-> <c- k>operator</c-><c- o>-></c-><c- p>(</c-><c- n>Self</c-><c- o>&amp;&amp;</c-> <c- k>this</c-><c- p>)</c-> <c- p>{</c->
    <c- k>return</c-> <c- n>addressof</c-><c- p>(</c-><c- k>this</c-><c- p>.</c-><c- n>m_value</c-><c- p>);</c->
  <c- p>}</c->
<c- p>};</c->
</pre>
     <tr>
      <th> <a href="#syntax-3">§3.1.3 Trailing type with identifier</a> 
      <th> <a href="#syntax-4">§3.1.4 Trailing type sans identifier</a> 
     <tr>
      <td>
<pre class="language-cpp highlight"><c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-> <c- n>T</c-><c- o>></c->
<c- k>struct</c-> <c- n>optional</c-> <c- p>{</c->
  <c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-> <c- n>Self</c-><c- o>></c->
  <c- k>constexpr</c-> <c- k>auto</c-><c- o>&amp;&amp;</c-> <c- n>value</c-><c- p>()</c-> <c- n>Self</c-><c- o>&amp;&amp;</c-> <c- n>self</c-> <c- p>{</c->
    <c- k>if</c-> <c- p>(</c-><c- o>!</c-><c- n>self</c-><c- p>.</c-><c- n>has_value</c-><c- p>())</c-> <c- p>{</c->
      <c- k>throw</c-> <c- n>bad_optional_access</c-><c- p>();</c->
    <c- p>}</c->
        
    <c- k>return</c-> <c- n>forward</c-><c- o>&lt;</c-><c- n>Self</c-><c- o>></c-><c- p>(</c-><c- n>self</c-><c- p>).</c-><c- n>m_value</c-><c- p>;</c->
  <c- p>}</c->
    
  <c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-> <c- n>Self</c-><c- o>></c->
  <c- k>constexpr</c-> <c- k>auto</c-> <c- k>operator</c-><c- o>-></c-><c- p>()</c-> <c- n>Self</c-> <c- n>self</c-> <c- p>{</c->
    <c- k>return</c-> <c- n>addressof</c-><c- p>(</c-><c- n>self</c-><c- p>.</c-><c- n>m_value</c-><c- p>);</c->
  <c- p>}</c->
<c- p>};</c->
</pre>
      <td>
<pre class="language-cpp highlight"><c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-> <c- n>T</c-><c- o>></c->
<c- k>struct</c-> <c- n>optional</c-> <c- p>{</c->
  <c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-> <c- n>Self</c-><c- o>></c->
  <c- k>constexpr</c-> <c- k>auto</c-><c- o>&amp;&amp;</c-> <c- n>value</c-><c- p>()</c-> <c- n>Self</c-><c- o>&amp;&amp;</c-> <c- p>{</c->
    <c- k>if</c-> <c- p>(</c-><c- o>!</c-><c- k>this</c-><c- o>-></c-><c- n>has_value</c-><c- p>())</c-> <c- p>{</c->
      <c- k>throw</c-> <c- n>bad_optional_access</c-><c- p>();</c->
    <c- p>}</c->
        
    <c- k>return</c-> <c- n>forward</c-><c- o>&lt;</c-><c- n>Self</c-><c- o>></c-><c- p>(</c-><c- o>*</c-><c- k>this</c-><c- p>).</c-><c- n>m_value</c-><c- p>;</c->
  <c- p>}</c->
    
  <c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-> <c- n>Self</c-><c- o>></c->
  <c- k>constexpr</c-> <c- k>auto</c-> <c- k>operator</c-><c- o>-></c-><c- p>()</c-> <c- n>Self</c-> <c- p>{</c->
    <c- k>return</c-> <c- n>addressof</c-><c- p>(</c-><c- k>this</c-><c- o>-></c-><c- n>m_value</c-><c- p>);</c->
  <c- p>}</c->
<c- p>};</c->
</pre>
   </table>
   <p>Note that the two syntaxes with trailing object types declare the object parameter to have only type <code class="highlight"><c- n>Self</c-></code>, while the explicit object parameter syntaxes still use <code class="highlight"><c- n>Self</c-><c- o>&amp;&amp;</c-></code>. This is explained further when we discuss taking <code class="highlight"><c- k>this</c-></code> <a href="#by-value-this">by value</a>.</p>
   <h3 class="heading settled" data-level="3.2" id="proposed-semantics"><span class="secno">3.2. </span><span class="content">Proposed semantics</span><a class="self-link" href="#proposed-semantics"></a></h3>
   <p>What follows is a description of how deducing <code class="highlight"><c- k>this</c-></code> affects all important language constructs — name lookup, type deduction, overload resolution, and so forth.</p>
   <p>This is a strict extension to the language. Depending on the syntax chosen, either all or nearly all existing syntax remains valid (see <a href="#parsing-issues">§3.2.10 Parsing issues</a> for a pathological case that may change some meaning should <a href="#syntax-3">§3.1.3 Trailing type with identifier</a> or <a href="#syntax-4">§3.1.4 Trailing type sans identifier</a> be chosen).</p>
   <h4 class="heading settled" data-level="3.2.1" id="name-lookup-candidate-functions"><span class="secno">3.2.1. </span><span class="content">Name lookup: candidate functions</span><a class="self-link" href="#name-lookup-candidate-functions"></a></h4>
   <p><strong>In C++17</strong>, name lookup includes both static and non-static member functions found by regular class lookup when invoking a named function or an operator, including the call operator, on an object of class type. Non-static member functions are treated as if there were an implicit object parameter whose type is an lvalue or rvalue reference to <em>cv</em> <code class="highlight"><c- n>X</c-></code> (where the reference and <em>cv</em> qualifiers are determined based on the function’s own qualifiers) which binds to the object on which the function was invoked.</p>
   <p>For non-static member functions using <strong>any of the new syntaxes</strong> (whether an <strong>explicit</strong> object parameter or a full <strong>explicit</strong> trailing object type), lookup will work the same way as other member functions in C++17, with one exception: rather than implicitly determining the type of the object parameter based on the <em>cv</em>- and <em>ref</em>-qualifiers of the member function, these are now explicitly determined by the provided type of the explicit object parameter. The following examples illustrate this concept, with the two other syntaxes omitted for brevity, since they behave identically.</p>
   <table style="width:100%">
    <tbody>
     <tr>
      <th style="width:33%">C++17
      <th style="width:33%"><a href="#syntax-1">§3.1.1 Explicit this-annotated parameter</a>
      <th style="width:33%"><a href="#syntax-4">§3.1.4 Trailing type sans identifier</a>
     <tr>
      <td>
<pre class="language-cpp highlight"><c- k>struct</c-> <c- n>X</c-> <c- p>{</c->
  <c- c1>// implicit object has type X&amp;</c->
  <c- b>void</c-> <c- n>foo</c-><c- p>()</c-> <c- o>&amp;</c-><c- p>;</c->

  <c- c1>// implicit object has type X const&amp;</c->
  <c- b>void</c-> <c- nf>foo</c-><c- p>()</c-> <c- k>const</c-><c- o>&amp;</c-><c- p>;</c->

  <c- c1>// implicit object has type X&amp;&amp;</c->
  <c- b>void</c-> <c- nf>bar</c-><c- p>()</c-> <c- o>&amp;&amp;</c-><c- p>;</c->
<c- p>};</c->
</pre>
      <td>
<pre class="language-cpp highlight"><c- k>struct</c-> <c- n>X</c-> <c- p>{</c->
  <c- c1>// explicit object has type X&amp;</c->
  <c- b>void</c-> <c- n>foo</c-><c- p>(</c-><c- k>this</c-> <c- n>X</c-><c- o>&amp;</c-><c- p>);</c->
  
  <c- c1>// explicit object has type X const&amp;</c->
  <c- b>void</c-> <c- nf>foo</c-><c- p>(</c-><c- k>this</c-> <c- n>X</c-> <c- k>const</c-><c- o>&amp;</c-><c- p>);</c->
  
  <c- c1>// explicit object has type X&amp;&amp;</c->
  <c- b>void</c-> <c- nf>bar</c-><c- p>(</c-><c- k>this</c-> <c- n>X</c-><c- o>&amp;&amp;</c-><c- p>);</c->
<c- p>};</c->
</pre>
      <td>
<pre class="language-cpp highlight"><c- k>struct</c-> <c- n>X</c-> <c- p>{</c->
  <c- c1>// explicit object has type X&amp;</c->
  <c- b>void</c-> <c- n>foo</c-><c- p>()</c-> <c- n>X</c-><c- o>&amp;</c-><c- p>;</c->

  <c- c1>// explicit object has type X const&amp;</c->
  <c- b>void</c-> <c- nf>foo</c-><c- p>()</c-> <c- n>X</c-> <c- k>const</c-><c- o>&amp;</c-><c- p>;</c->

  <c- c1>// explicit object type X&amp;&amp;</c->
  <c- b>void</c-> <c- nf>bar</c-><c- p>()</c-> <c- n>X</c-><c- o>&amp;&amp;</c-><c- p>;</c->
<c- p>};</c->
</pre>
   </table>
   <p>Name lookup on an expression like <code class="highlight"><c- n>obj</c-><c- p>.</c-><c- n>foo</c-><c- p>()</c-></code> in C++17 would find both overloads of <code class="highlight"><c- n>foo</c-></code> in the first column, with the non-const overload discarded should <code class="highlight"><c- n>obj</c-></code> be const.</p>
   <p>With any of the proposed syntaxes, <code class="highlight"><c- n>obj</c-><c- p>.</c-><c- n>foo</c-><c- p>()</c-></code> would continue to find both overloads of <code class="highlight"><c- n>foo</c-></code>, with identical behaviour to C++17.</p>
   <p>The only change in how we look up candidate functions is in the case of an explicit object parameter, where the argument list is shifted by one. The first listed parameter is bound to the object argument, and the second listed parameter corresponds to the first argument of the call expression.</p>
   <p>This paper does not propose any changes to overload <em>resolution</em> but merely suggests extending the candidate set to include non-static member functions and member function templates written in a new syntax. Therefore, given a call to <code class="highlight"><c- n>x</c-><c- p>.</c-><c- n>foo</c-><c- p>()</c-></code>, overload resolution would still select the first <code class="highlight"><c- n>foo</c-><c- p>()</c-></code> overload if <code class="highlight"><c- n>x</c-></code> is not <code class="highlight"><c- k>const</c-></code> and the second if it is.</p>
   <p>The behaviors of the three columns are exactly equivalent as proposed.</p>
   <p>The only change as far as candidates are concerned is that the proposal allows for deduction of the object parameter, which is new for the language.</p>
   <h4 class="heading settled" data-level="3.2.2" id="type-deduction"><span class="secno">3.2.2. </span><span class="content">Type deduction</span><a class="self-link" href="#type-deduction"></a></h4>
   <p>One of the main motivations of this proposal is to deduce the <em>cv</em>-qualifiers and value category of the class object, which requires that the explicit member object or type be deducible from the object on which the member function is invoked.</p>
   <p>If the type of the object parameter is a template parameter, all of the usual template deduction rules apply as expected:</p>
   <table style="width:100%">
    <tbody>
     <tr>
      <th style="width:50%"><a href="#syntax-1">§3.1.1 Explicit this-annotated parameter</a>
      <th style="width:50%"><a href="#syntax-4">§3.1.4 Trailing type sans identifier</a>
     <tr>
      <td>
<pre class="language-cpp highlight"><c- k>struct</c-> <c- n>X</c-> <c- p>{</c->
  <c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-> <c- n>Self</c-><c- o>></c->
  <c- b>void</c-> <c- n>foo</c-><c- p>(</c-><c- k>this</c-> <c- n>Self</c-><c- o>&amp;&amp;</c-><c- p>,</c-> <c- b>int</c-><c- p>);</c->
<c- p>};</c->

<c- k>struct</c-> <c- nl>D</c-> <c- p>:</c-> <c- n>X</c-> <c- p>{</c-> <c- p>};</c->

<c- b>void</c-> <c- nf>ex</c-><c- p>(</c-><c- n>X</c-><c- o>&amp;</c-> <c- n>x</c-><c- p>,</c-> <c- n>D</c-><c- o>&amp;</c-> <c- n>d</c-><c- p>)</c-> <c- p>{</c->
    <c- n>x</c-><c- p>.</c-><c- n>foo</c-><c- p>(</c-><c- mi>1</c-><c- p>);</c->       <c- c1>// Self=X&amp;</c->
    <c- n>move</c-><c- p>(</c-><c- n>x</c-><c- p>).</c-><c- n>foo</c-><c- p>(</c-><c- mi>2</c-><c- p>);</c-> <c- c1>// Self=X</c->
    <c- n>d</c-><c- p>.</c-><c- n>foo</c-><c- p>(</c-><c- mi>3</c-><c- p>);</c->       <c- c1>// Self=D&amp;</c->
<c- p>}</c->
</pre>
      <td>
<pre class="language-cpp highlight"><c- k>struct</c-> <c- n>X</c-> <c- p>{</c->
  <c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-> <c- n>Self</c-><c- o>></c->
  <c- b>void</c-> <c- n>foo</c-><c- p>(</c-><c- b>int</c-><c- p>)</c-> <c- n>Self</c-><c- o>&amp;&amp;</c-><c- p>;</c->
<c- p>};</c->

<c- k>struct</c-> <c- nl>D</c-> <c- p>:</c-> <c- n>X</c-> <c- p>{</c-> <c- p>};</c->

<c- b>void</c-> <c- nf>ex</c-><c- p>(</c-><c- n>X</c-><c- o>&amp;</c-> <c- n>x</c-><c- p>,</c-> <c- n>D</c-><c- o>&amp;</c-> <c- n>d</c-><c- p>)</c-> <c- p>{</c->
    <c- n>x</c-><c- p>.</c-><c- n>foo</c-><c- p>(</c-><c- mi>1</c-><c- p>);</c->       <c- c1>// Self=X&amp;</c->
    <c- n>move</c-><c- p>(</c-><c- n>x</c-><c- p>).</c-><c- n>foo</c-><c- p>(</c-><c- mi>2</c-><c- p>);</c-> <c- c1>// Self=X</c->
    <c- n>d</c-><c- p>.</c-><c- n>foo</c-><c- p>(</c-><c- mi>3</c-><c- p>);</c->       <c- c1>// Self=D&amp;</c->
<c- p>}</c->
</pre>
   </table>
   <p>It’s important to stress that deduction is able to deduce a derived type, which is extremely powerful. In the last line, regardless of syntax, <code class="highlight"><c- n>Self</c-></code> deduces as <code class="highlight"><c- n>D</c-><c- o>&amp;</c-></code>. This has implications for <a href="#name-lookup-within-member-functions">§3.2.4 Name lookup: within member functions</a>, and leads to a potential <a href="#potential-extensions">template deduction extension</a>.</p>
   <h4 class="heading settled" data-level="3.2.3" id="by-value-this"><span class="secno">3.2.3. </span><span class="content">By value <code class="highlight"><c- k>this</c-></code></span><a class="self-link" href="#by-value-this"></a></h4>
   <p>But what if the explicit type does not have reference type? This is one key point where the proposed rules for having an explicit object parameter and having an trailing object type diverge. For both syntaxes, there is a clear meaning — it’s just that it is very different clear meaning between the two.</p>
   <h5 class="heading settled" data-level="3.2.3.1" id="by-value-this-explicit"><span class="secno">3.2.3.1. </span><span class="content">By value <code class="highlight"><c- k>this</c-></code> in explicit syntaxes</span><a class="self-link" href="#by-value-this-explicit"></a></h5>
   <p>In the case of <a href="#syntax-1">§3.1.1 Explicit this-annotated parameter</a> and <a href="#syntax-2">§3.1.2 Explicit this parameter</a>, what should this mean:</p>
<pre class="language-c++ highlight"><c- k>struct</c-> <c- n>less_than</c-> <c- p>{</c->
    <c- n>template</c-> <c- o>&lt;</c-><c- kr>typename</c-> <c- n>T</c-><c- p>,</c-> <c- kr>typename</c-> <c- n>U</c-><c- o>></c->
    <c- b>bool</c-> <c- n>operator</c-><c- p>()(</c-><c- n>this</c-> <c- n>less_than</c-><c- p>,</c-> <c- n>T</c-> <c- k>const</c-><c- o>&amp;</c-> <c- n>lhs</c-><c- p>,</c-> <c- n>U</c-> <c- k>const</c-><c- o>&amp;</c-> <c- n>rhs</c-><c- p>)</c-> <c- p>{</c->
        <c- k>return</c-> <c- n>lhs</c-> <c- o>&lt;</c-> <c- n>rhs</c-><c- p>;</c->
    <c- p>}</c->
<c- p>};</c->

<c- n>less_than</c-><c- p>{}(</c-><c- mi>4</c-><c- p>,</c-> <c- mi>5</c-><c- p>);</c->
</pre>
   <p>Clearly, the parameter specification should not lie, and the first parameter (<code class="highlight"><c- n>less_than</c-><c- p>{}</c-></code>) is passed by value.</p>
   <p>Following the proposed rules for candidate lookup, the call operator here would be a candidate, with the object parameter binding to the (empty) object and the other two parameters binding to the arguments. Having a value parameter is nothing new in the language at all — it has a clear and obvious meaning, but we’ve never been able to take an object parameter by value before. For cases in which this might be desirable, see <a href="#by-value-member-functions">§4.4 By-value member functions</a>.</p>
   <p>However, with a by-value explicit object parameter, we still must answer the question of what <code class="highlight"><c- k>this</c-></code> refers to within the function body. Regardless of the choice we make for <a href="#name-lookup-within-member-functions">§3.2.4 Name lookup: within member functions</a>, there is only one meaningful semantic choice here: there is no <code class="highlight"><c- k>this</c-></code>. In the above example, <code class="highlight"><c- n>less_than</c-></code> doesn’t <em>refer</em> to the object parameter, it <em>is</em> the only object parameter. Declaring a function in this way is equivalent to declaring a non-member <code class="highlight"><c- k>friend</c-></code> function, except that we effectively opt-in to the usual member function call syntax. This also determines its pointer type — it is a free function type.</p>
   <h5 class="heading settled" data-level="3.2.3.2" id="by-value-this-trailing"><span class="secno">3.2.3.2. </span><span class="content">By value <code class="highlight"><c- k>this</c-></code> in trailing syntaxes</span><a class="self-link" href="#by-value-this-trailing"></a></h5>
   <p>In the case of trailing object type, what should this mean:</p>
<pre class="language-c++ highlight"><c- n>template</c-> <c- o>&lt;</c-><c- kr>typename</c-> <c- n>T</c-><c- p>,</c-> <c- b>size_t</c-> <c- n>N</c-><c- o>></c->
<c- k>struct</c-> <c- n>array</c-> <c- p>{</c->
    <c- n>template</c-> <c- o>&lt;</c-><c- kr>typename</c-> <c- n>Self</c-><c- o>></c->
    <c- k>auto</c-><c- o>&amp;</c-> <c- n>operator</c-><c- p>[](</c-><c- b>size_t</c-><c- p>)</c-> <c- n>Self</c-><c- p>;</c->
<c- p>};</c->
</pre>
   <p>Clearly, since the object type is an <em>optional</em> part of the syntax, omitting it should produce the same results as it would currently.</p>
   <p>A common source of member function duplication revolves around wanting non-<code class="highlight"><c- k>const</c-></code> and <code class="highlight"><c- k>const</c-></code> overloads of a member function that otherwise do exactly the same thing. The normal template deduction rules would drop <em>cv</em>-qualifiers, meaning:</p>
<pre class="language-c++ highlight"><c- n>using</c-> <c- n>A</c-> <c- o>=</c-> <c- n>array</c-><c- o>&lt;</c-><c- b>int</c-><c- p>,</c-> <c- mi>10</c-><c- o>></c-><c- p>;</c->
<c- b>void</c-> <c- nf>ex</c-><c- p>(</c-><c- n>A</c-><c- o>&amp;</c-> <c- n>a</c-><c- p>,</c-> <c- n>A</c-> <c- k>const</c-><c- o>&amp;</c-><c- p>,</c-> <c- n>ca</c-><c- p>)</c-> <c- p>{</c->
    <c- n>a</c-><c- p>[</c-><c- mi>0</c-><c- p>];</c->  <c- c1>// deduces Self=A</c->
    <c- n>ca</c-><c- p>[</c-><c- mi>0</c-><c- p>];</c-> <c- c1>// deduces Self=A, same function</c->
<c- p>}</c->
</pre>
   <p>But with normal member function declarations today, we don’t have the same notion of a "value." The implicit object parameter is always a reference. We’re used to writing either nothing or <code class="highlight"><c- k>const</c-></code> at the end of member functions, which is analogous to writing <code class="highlight"><c- n>C</c-></code> or <code class="highlight"><c- n>C</c-> <c- k>const</c-></code>. It would follow that allowing the deduction of a naked (i.e. non-reference) template parameter to preserve <em>cv</em>-qualifiers would produce the expected behavior and be quite useful.</p>
   <p>Should the trailing syntax be chosen, we propose that <code class="highlight"><c- n>ca</c-><c- p>[</c-><c- mi>0</c-><c- p>]</c-></code> deduces <code class="highlight"><c- n>Self</c-></code> as <code class="highlight"><c- n>A</c-> <c- k>const</c-></code> in the previous example.</p>
   <p>This mimics today’s behavior where a trailing <code class="highlight"><c- k>const</c-></code> qualifier does not mean <code class="highlight"><c- k>const</c-><c- o>&amp;</c-></code> — it only means <code class="highlight"><c- k>const</c-></code>. Without such a change to template deduction, <code class="highlight"><c- n>Self</c-></code> would always deduce as <code class="highlight"><c- n>A</c-></code>, and hence be pointless; <code class="highlight"><c- n>Self</c-><c- o>&amp;</c-></code> would deduce as <code class="highlight"><c- n>A</c-><c- o>&amp;</c-></code> or <code class="highlight"><c- n>A</c-> <c- k>const</c-><c- o>&amp;</c-></code> but not allow binding to rvalues; and <code class="highlight"><c- n>Self</c-><c- o>&amp;&amp;</c-></code> would give us different functions for lvalues and rvalues, which is unnecessary and leads to code bloat.</p>
   <h4 class="heading settled" data-level="3.2.4" id="name-lookup-within-member-functions"><span class="secno">3.2.4. </span><span class="content">Name lookup: within member functions</span><a class="self-link" href="#name-lookup-within-member-functions"></a></h4>
   <p>So far, we’ve only considered how member functions with trailing object types are found with name lookup and how they deduce that parameter. Now we move on to how the bodies of these functions actually behave.</p>
   <p>Since either the explicit object parameter or trailing object type is deduced from the object on which the function is called, this has the possible effect of deducing <em>derived</em> types. We must carefully consider how name lookup works in this context.</p>
   <p>To avoid repetition, we’ll use an explicit object parameter for this example. Other syntaxes have identical or a subset of these possibilities, modulo some renaming:</p>
<pre class="language-cpp highlight"><c- k>struct</c-> <c- n>B</c-> <c- p>{</c->
    <c- b>int</c-> <c- n>i</c-> <c- o>=</c-> <c- mi>0</c-><c- p>;</c->

    <c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-> <c- n>Self</c-><c- o>></c-> <c- k>auto</c-><c- o>&amp;&amp;</c-> <c- n>f1</c-><c- p>(</c-><c- k>this</c-> <c- n>Self</c-><c- o>&amp;&amp;</c-><c- p>)</c-> <c- p>{</c-> <c- k>return</c-> <c- n>i</c-><c- p>;</c->  <c- p>}</c->
    <c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-> <c- n>Self</c-><c- o>></c-> <c- k>auto</c-><c- o>&amp;&amp;</c-> <c- n>f2</c-><c- p>(</c-><c- k>this</c-> <c- n>Self</c-><c- o>&amp;&amp;</c-><c- p>)</c-> <c- p>{</c-> <c- k>return</c-> <c- k>this</c-><c- o>-></c-><c- n>i</c-><c- p>;</c-> <c- p>}</c->    
    <c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-> <c- n>Self</c-><c- o>></c-> <c- k>auto</c-><c- o>&amp;&amp;</c-> <c- n>f3</c-><c- p>(</c-><c- k>this</c-> <c- n>Self</c-><c- o>&amp;&amp;</c-><c- p>)</c-> <c- p>{</c-> <c- k>return</c-> <c- n>forward_like</c-><c- o>&lt;</c-><c- n>Self</c-><c- o>></c-><c- p>(</c-><c- o>*</c-><c- k>this</c-><c- p>).</c-><c- n>i</c-><c- p>;</c-> <c- p>}</c->    
    <c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-> <c- n>Self</c-><c- o>></c-> <c- k>auto</c-><c- o>&amp;&amp;</c-> <c- n>f4</c-><c- p>(</c-><c- k>this</c-> <c- n>Self</c-><c- o>&amp;&amp;</c-><c- p>)</c-> <c- p>{</c-> <c- k>return</c-> <c- n>forward</c-><c- o>&lt;</c-><c- n>Self</c-><c- o>></c-><c- p>(</c-><c- o>*</c-><c- k>this</c-><c- p>).</c-><c- n>i</c-><c- p>;</c-> <c- p>}</c->        
    <c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-> <c- n>Self</c-><c- o>></c-> <c- k>auto</c-><c- o>&amp;&amp;</c-> <c- n>f5</c-><c- p>(</c-><c- k>this</c-> <c- n>Self</c-><c- o>&amp;&amp;</c-> <c- n>self</c-><c- p>)</c-> <c- p>{</c-> <c- k>return</c-> <c- n>forward</c-><c- o>&lt;</c-><c- n>Self</c-><c- o>></c-><c- p>(</c-><c- n>self</c-><c- p>).</c-><c- n>i</c-><c- p>;</c-> <c- p>}</c->
<c- p>};</c->

<c- k>struct</c-> <c- nl>D</c-> <c- p>:</c-> <c- n>B</c-> <c- p>{</c->
    <c- c1>// shadows B::i</c->
    <c- b>double</c-> <c- n>i</c-> <c- o>=</c-> <c- mf>3.14</c-><c- p>;</c->
<c- p>};</c->
</pre>
   <p>The question is, what do each of these five functions do? Should any of them be ill-formed? What is the safest option?</p>
   <p>We believe that there are three approaches to choose from:</p>
   <ol>
    <li data-md>
     <p>If there is an explicit object parameter, <code class="highlight"><c- k>this</c-></code> is inaccessible, and each access must be through <code class="highlight"><c- n>self</c-></code>. There is no implicit lookup of members through <code class="highlight"><c- k>this</c-></code>. This makes <code class="highlight"><c- n>f1</c-></code> through <code class="highlight"><c- n>f4</c-></code> ill-formed and only <code class="highlight"><c- n>f5</c-></code> well-formed. However, while <code class="highlight"><c- n>B</c-><c- p>().</c-><c- n>f5</c-><c- p>()</c-></code> returns a reference to <code class="highlight"><c- n>B</c-><c- o>::</c-><c- n>i</c-></code>, <code class="highlight"><c- n>D</c-><c- p>().</c-><c- n>f5</c-><c- p>()</c-></code> returns a reference to <code class="highlight"><c- n>D</c-><c- o>::</c-><c- n>i</c-></code>, since <code class="highlight"><c- n>self</c-></code> is a reference to <code class="highlight"><c- n>D</c-></code>.</p>
    <li data-md>
     <p>If there is an explicit object parameter, <code class="highlight"><c- k>this</c-></code> is accessible and points to the base subobject. There is no implicit lookup of members; all access must be through <code class="highlight"><c- k>this</c-></code> or <code class="highlight"><c- n>self</c-></code> explicitly. This makes <code class="highlight"><c- n>f1</c-></code> ill-formed. <code class="highlight"><c- n>f2</c-></code> would be well-formed and always return a reference to <code class="highlight"><c- n>B</c-><c- o>::</c-><c- n>i</c-></code>. Most importantly, <code class="highlight"><c- k>this</c-></code> would be <em>dependent</em> if the explicit object parameter was deduced. <code class="highlight"><c- k>this</c-><c- o>-></c-><c- n>i</c-></code> is always going to be an <code class="highlight"><c- b>int</c-></code> but it could be either an <code class="highlight"><c- b>int</c-></code> or an <code class="highlight"><c- b>int</c-> <c- k>const</c-></code> depending on whether the <code class="highlight"><c- n>B</c-></code> object is const. <code class="highlight"><c- n>f3</c-></code> would always be well-formed and would be the correct way to return a forwarding reference to <code class="highlight"><c- n>B</c-><c- o>::</c-><c- n>i</c-></code>. <code class="highlight"><c- n>f4</c-></code> would be well-formed when invoked on <code class="highlight"><c- n>B</c-></code> but ill-formed if invoked on <code class="highlight"><c- n>D</c-></code> because of the requested implicit downcast. As before, <code class="highlight"><c- n>f5</c-></code> would be well-formed.</p>
    <li data-md>
     <p><code class="highlight"><c- k>this</c-></code> is always accessible and points to the base subobject; we allow implicit lookup as in C++17. This is mostly the same as the previous choice, except that now <code class="highlight"><c- n>f1</c-></code> is well-formed and exactly equivalent to <code class="highlight"><c- n>f2</c-></code>.</p>
   </ol>
   <p>Based on these three name lookup semantics, here is a comparison of the implementation of <code class="highlight"><c- n>optional</c-><c- o>::</c-><c- n>value</c-><c- p>()</c-></code> that takes great care to avoid accessing anything from the derived object:</p>
   <table style="width:100%">
    <tbody>
     <tr>
      <th><code class="highlight"><c- k>this</c-></code><br>inaccessible
      <td>
<pre class="language-c++ highlight"><c- n>template</c-> <c- o>&lt;</c-><c- kr>typename</c-> <c- n>Self</c-><c- o>></c->
<c- k>auto</c-><c- o>&amp;&amp;</c-> <c- n>value</c-><c- p>(</c-><c- n>this</c-> <c- n>Self</c-><c- o>&amp;&amp;</c-> <c- n>self</c-><c- p>)</c-> <c- p>{</c->
  <c- k>if</c-> <c- p>(</c-><c- o>!</c-><c- n>self</c-><c- p>.</c-><c- n>optional</c-><c- o>::</c-><c- n>has_value</c-><c- p>())</c-> <c- p>{</c->
    <c- n>throw</c-> <c- n>bad_optional_access</c-><c- p>();</c->
  <c- p>}</c->
  
  <c- k>return</c-> <c- n>forward</c-><c- o>&lt;</c-><c- n>Self</c-><c- o>></c-><c- p>(</c-><c- n>self</c-><c- p>).</c-><c- n>optional</c-><c- o>::</c-><c- n>m_value</c-><c- p>;</c->
<c- p>}</c->
</pre>
     <tr>
      <th><code class="highlight"><c- k>this</c-></code> accessible<br>but explicit
      <td>
<pre class="language-c++ highlight"><c- n>template</c-> <c- o>&lt;</c-><c- kr>typename</c-> <c- n>Self</c-><c- o>></c->
<c- k>auto</c-><c- o>&amp;&amp;</c-> <c- n>value</c-><c- p>(</c-><c- n>this</c-> <c- n>Self</c-><c- o>&amp;&amp;</c-><c- p>)</c-> <c- p>{</c->
  <c- k>if</c-> <c- p>(</c-><c- o>!</c-><c- n>this</c-><c- o>-></c-><c- n>has_value</c-><c- p>())</c-> <c- p>{</c->
    <c- n>throw</c-> <c- n>bad_optional_access</c-><c- p>();</c->
  <c- p>}</c->
  
  <c- k>return</c-> <c- n>forward_like</c-><c- o>&lt;</c-><c- n>Self</c-><c- o>></c-><c- p>(</c-><c- o>*</c-><c- n>this</c-><c- p>).</c-><c- n>m_value</c-><c- p>;</c->
<c- p>}</c->
</pre>
     <tr>
      <th><code class="highlight"><c- k>this</c-></code> accessible<br>and implicit
      <td>
<pre class="language-c++ highlight"><c- n>template</c-> <c- o>&lt;</c-><c- kr>typename</c-> <c- n>Self</c-><c- o>></c->
<c- k>auto</c-><c- o>&amp;&amp;</c-> <c- n>value</c-><c- p>(</c-><c- n>this</c-> <c- n>Self</c-><c- o>&amp;&amp;</c-><c- p>)</c-> <c- p>{</c->
  <c- k>if</c-> <c- p>(</c-><c- o>!</c-><c- n>has_value</c-><c- p>())</c-> <c- p>{</c->
    <c- n>throw</c-> <c- n>bad_optional_access</c-><c- p>();</c->
  <c- p>}</c->
  
  <c- k>return</c-> <c- n>forward_like</c-><c- o>&lt;</c-><c- n>Self</c-><c- o>></c-><c- p>(</c-><c- n>m_value</c-><c- p>);</c->
<c- p>}</c->
</pre>
   </table>
   <p>Note that in the latter two choices, we do not even provide a name to the explicit object parameter, since it is not needed, although we could have chosen to do so anyway.</p>
   <p>What do these options mean when considering the trailing type syntax? If we allow an <em>identifier</em>, then the name lookup semantics would be exactly the same as having an explicit object parameter — the named parameter is in a different location in the declaration, but otherwise has the same meaning.</p>
   <p>If we take the trailing object type syntax <em>without an identifier</em>, we can’t differentiate between what <code class="highlight"><c- k>this</c-></code> might refer to and what <code class="highlight"><c- n>self</c-></code> might refer to. We can really only have one possible name: <code class="highlight"><c- k>this</c-></code>. And <code class="highlight"><c- k>this</c-></code> would now have to change types, becoming a <code class="highlight"><c- k>const</c-></code> pointer to <code class="highlight"><c- n>remove_reference_t</c-><c- o>&lt;</c-><c- n>T</c-><c- o>></c-></code>.</p>
   <p>The same is true of the <a href="#syntax-2">§3.1.2 Explicit this parameter</a> syntax: <code class="highlight"><c- k>this</c-></code> is the only name that exists and refers to the most derived object, so implicit access is disallowed.</p>
<pre class="language-cpp highlight"><c- k>struct</c-> <c- n>X</c-> <c- p>{</c->
    <c- b>void</c-> <c- n>a</c-><c- p>();</c->            <c- c1>// this is a X* const</c->
    <c- b>void</c-> <c- nf>b</c-><c- p>()</c-> <c- k>const</c-><c- p>;</c->      <c- c1>// this is a X const* const</c->
    <c- b>void</c-> <c- nf>c</c-><c- p>()</c-> <c- o>&amp;&amp;</c-><c- p>;</c->         <c- c1>// this is a X* const (ref-qualifiers don’t count)</c->

    <c- b>void</c-> <c- nf>d</c-><c- p>()</c-> <c- n>X</c-><c- p>;</c->          <c- c1>// this is a X* const (same as a)</c->
    <c- b>void</c-> <c- nf>e</c-><c- p>()</c-> <c- n>X</c-><c- o>&amp;&amp;</c-><c- p>;</c->        <c- c1>// this is a X* const (same as c)</c->
    
    <c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-> <c- n>S</c-><c- o>></c->
    <c- b>void</c-> <c- n>f</c-><c- p>()</c-> <c- n>S</c-><c- p>;</c->          <c- c1>// this is a S* const (which can be a pointer to const or not!)</c->
    <c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-> <c- n>S</c-><c- o>></c->
    <c- b>void</c-> <c- n>g</c-><c- p>()</c-> <c- n>S</c-><c- o>&amp;</c-><c- p>;</c->         <c- c1>// this is a S* const</c->
    <c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-> <c- n>S</c-><c- o>></c->
    <c- b>void</c-> <c- n>h</c-><c- p>()</c-> <c- n>S</c-><c- o>&amp;&amp;</c-><c- p>;</c->        <c- c1>// this is a remove_reference_t&lt;S>* const</c->
<c- p>};</c->
</pre>
   <p>For some of these member functions, <code class="highlight"><c- k>this</c-></code> might not point to <code class="highlight"><c- n>X</c-></code>. It might point to a type derived from <code class="highlight"><c- n>X</c-></code>. With the trailing type syntax, we end up with a slightly different choice of syntaxes:</p>
<pre class="language-c++ highlight"><c- k>struct</c-> <c- n>B</c-> <c- p>{</c->
    <c- b>int</c-> <c- n>i</c-> <c- o>=</c-> <c- mi>0</c-><c- p>;</c->

    <c- n>template</c-> <c- o>&lt;</c-><c- kr>typename</c-> <c- n>Self</c-><c- o>></c-> <c- k>auto</c-><c- o>&amp;&amp;</c-> <c- n>f1</c-><c- p>()</c-> <c- n>Self</c-><c- o>&amp;&amp;</c-> <c- p>{</c-> <c- k>return</c-> <c- n>i</c-><c- p>;</c->  <c- p>}</c->
    <c- n>template</c-> <c- o>&lt;</c-><c- kr>typename</c-> <c- n>Self</c-><c- o>></c-> <c- k>auto</c-><c- o>&amp;&amp;</c-> <c- n>f2</c-><c- p>()</c-> <c- n>Self</c-><c- o>&amp;&amp;</c-> <c- p>{</c-> <c- k>return</c-> <c- n>this</c-><c- o>-></c-><c- n>i</c-><c- p>;</c-> <c- p>}</c->    
    <c- n>template</c-> <c- o>&lt;</c-><c- kr>typename</c-> <c- n>Self</c-><c- o>></c-> <c- k>auto</c-><c- o>&amp;&amp;</c-> <c- n>f3</c-><c- p>()</c-> <c- n>Self</c-><c- o>&amp;&amp;</c-> <c- p>{</c-> <c- k>return</c-> <c- n>forward_like</c-><c- o>&lt;</c-><c- n>Self</c-><c- o>></c-><c- p>(</c-><c- o>*</c-><c- n>this</c-><c- p>).</c-><c- n>i</c-><c- p>;</c-> <c- p>}</c->    
    <c- n>template</c-> <c- o>&lt;</c-><c- kr>typename</c-> <c- n>Self</c-><c- o>></c-> <c- k>auto</c-><c- o>&amp;&amp;</c-> <c- n>f4</c-><c- p>()</c-> <c- n>Self</c-><c- o>&amp;&amp;</c-> <c- p>{</c-> <c- k>return</c-> <c- n>forward</c-><c- o>&lt;</c-><c- n>Self</c-><c- o>></c-><c- p>(</c-><c- o>*</c-><c- n>this</c-><c- p>).</c-><c- n>i</c-><c- p>;</c-> <c- p>}</c->        
<c- p>};</c->
</pre>
   <p>First, note that <code class="highlight"><c- n>f3</c-></code> and <code class="highlight"><c- n>f4</c-></code> are equivalent with this syntax. Since <code class="highlight"><c- k>this</c-></code> is a pointer to <code class="highlight"><c- n>Self</c-></code>, there is no differentiation. Our only real options are:</p>
   <ol>
    <li data-md>
     <p><code class="highlight"><c- k>this</c-></code> is not implicitly accessible and you need to qualify every access — that is, <code class="highlight"><c- n>f1</c-></code> is ill-formed.</p>
    <li data-md>
     <p><code class="highlight"><c- k>this</c-></code> is implicitly accessible, but since <code class="highlight"><c- k>this</c-></code> is no longer necessarily a pointer to <code class="highlight"><c- n>B</c-></code>, <code class="highlight"><c- n>f1</c-></code> does not necessary return <code class="highlight"><c- n>B</c-><c- o>::</c-><c- n>i</c-></code>.</p>
   </ol>
   <p>Without an identifier, there is no way to syntactically differentiate between <em>specifically</em> accessing something in <code class="highlight"><c- n>B</c-></code> and accessing something through whatever is deduced as the object parameter. The same is true if, when having an identifier, we choose option #1 (<code class="highlight"><c- k>this</c-></code> is always inaccessible). We would have to write one of the following:</p>
<pre class="language-cpp highlight"><c- c1>// for each of these examples, we are using 'self' as the named</c->
<c- c1>// identifier for the object parameter. If we are using the syntax</c->
<c- c1>// that does not allow for an identifier, replace it mentally with</c->
<c- c1>// *this instead.</c->

<c- c1>// explicitly cast self to the appropriately qualified B</c->
<c- c1>// note that we have to cast self, not self.i</c->
<c- k>return</c-> <c- k>static_cast</c-><c- o>&lt;</c-><c- n>like_t</c-><c- o>&lt;</c-><c- n>Self</c-><c- p>,</c-> <c- n>B</c-><c- o>>&amp;&amp;></c-><c- p>(</c-><c- n>self</c-><c- p>).</c-><c- n>i</c-><c- p>;</c->

<c- c1>// use the explicit subobject syntax. Note that this is always</c->
<c- c1>// an lvalue reference - not a forwarding reference</c->
<c- k>return</c-> <c- n>self</c-><c- p>.</c-><c- n>B</c-><c- o>::</c-><c- n>i</c-><c- p>;</c->

<c- c1>// use the explicit subobject syntax to get a forwarding reference</c->
<c- k>return</c-> <c- n>forward</c-><c- o>&lt;</c-><c- n>Self</c-><c- o>></c-><c- p>(</c-><c- n>self</c-><c- p>).</c-><c- n>B</c-><c- o>::</c-><c- n>i</c-><c- p>;</c->
</pre>
   <p>This is quite complex, so we believe there to be a benefit in having the ability to syntactically differentiate between referring to the deduced most-derived object and the non-deduced class-we’re-in object.</p>
   <h4 class="heading settled" data-level="3.2.5" id="writing-function-pointer-types"><span class="secno">3.2.5. </span><span class="content">Writing the function pointer types for such functions</span><a class="self-link" href="#writing-function-pointer-types"></a></h4>
   <p>The proposed change allows us to deduce the object parameter’s value category and <em>cv</em>-qualifiers, but the member functions themselves are otherwise the same as today, with no change to their types.</p>
   <p>In other words, given:</p>
<pre class="language-cpp highlight"><c- k>struct</c-> <c- n>Y</c-> <c- p>{</c->
    <c- b>int</c-> <c- n>f</c-><c- p>(</c-><c- b>int</c-><c- p>,</c-> <c- b>int</c-><c- p>)</c-> <c- k>const</c-><c- o>&amp;</c-><c- p>;</c->
    <c- b>int</c-> <c- nf>g</c-><c- p>(</c-><c- b>int</c-><c- p>,</c-> <c- b>int</c-><c- p>)</c-> <c- n>Y</c-> <c- k>const</c-><c- o>&amp;</c-><c- p>;</c->
    <c- b>int</c-> <c- nf>h</c-><c- p>(</c-><c- k>this</c-> <c- n>Y</c-> <c- k>const</c-><c- o>&amp;</c-><c- p>,</c-> <c- b>int</c-><c- p>,</c-> <c- b>int</c-><c- p>);</c->
<c- p>};</c->
</pre>
   <p><code class="highlight"><c- n>Y</c-><c- o>::</c-><c- n>f</c-></code>, <code class="highlight"><c- n>Y</c-><c- o>::</c-><c- n>g</c-></code>, and <code class="highlight"><c- n>Y</c-><c- o>::</c-><c- n>h</c-></code> are equivalent from a signature standpoint, so all of them have type <code class="highlight"><c- b>int</c-><c- p>(</c-><c- n>Y</c-><c- o>::*</c-><c- p>)(</c-><c- b>int</c-><c- p>,</c-> <c- b>int</c-><c- p>)</c-> <c- k>const</c-><c- o>&amp;</c-></code>.</p>
   <p>This becomes especially interesting when deduction kicks in. These rules are the same regardless of syntax, so to avoid repetition, we’ll use the explicit object parameter syntax:</p>
<pre class="language-cpp highlight"><c- k>struct</c-> <c- n>B</c-> <c- p>{</c->
    <c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-> <c- n>Self</c-><c- o>></c->
    <c- b>void</c-> <c- n>foo</c-><c- p>(</c-><c- k>this</c-> <c- n>Self</c-><c- o>&amp;&amp;</c-><c- p>);</c->
<c- p>};</c->

<c- k>struct</c-> <c- nl>D</c-> <c- p>:</c-> <c- n>B</c-> <c- p>{</c-> <c- p>};</c->
</pre>
   <p>The type of <code class="highlight"><c- o>&amp;</c-><c- n>B</c-><c- o>::</c-><c- n>foo</c-><c- o>&lt;</c-><c- n>B</c-><c- o>></c-></code> is <code class="highlight"><c- b>void</c-> <c- p>(</c-><c- n>B</c-><c- o>::*</c-><c- p>)()</c-> <c- o>&amp;&amp;</c-></code> and the type of <code class="highlight"><c- o>&amp;</c-><c- n>B</c-><c- o>::</c-><c- n>foo</c-><c- o>&lt;</c-><c- n>B</c-> <c- k>const</c-><c- o>&amp;></c-></code> is <code class="highlight"><c- b>void</c-> <c- p>(</c-><c- n>B</c-><c- o>::*</c-><c- p>)()</c-> <c- k>const</c-><c- o>&amp;</c-></code>. This is just a normal member function. The type of <code class="highlight"><c- o>&amp;</c-><c- n>D</c-><c- o>::</c-><c- n>foo</c-><c- o>&lt;</c-><c- n>B</c-><c- o>></c-></code> is <code class="highlight"><c- b>void</c-> <c- p>(</c-><c- n>B</c-><c- o>::*</c-><c- p>)()</c-> <c- o>&amp;&amp;</c-></code>. This is effectively the same thing that would happen if <code class="highlight"><c- n>foo</c-></code> were a normal C++17 member function. The type of <code class="highlight"><c- o>&amp;</c-><c- n>B</c-><c- o>::</c-><c- n>foo</c-><c- o>&lt;</c-><c- n>D</c-><c- o>></c-></code> is <code class="highlight"><c- b>void</c-> <c- p>(</c-><c- n>D</c-><c- o>::*</c-><c- p>)()</c-> <c- o>&amp;&amp;</c-></code>. That is, it behaves as if it were a member function of <code class="highlight"><c- n>D</c-></code>.</p>
   <p>By-value object parameters can be allowed for either <a href="#syntax-1">§3.1.1 Explicit this-annotated parameter</a> or <a href="#syntax-2">§3.1.2 Explicit this parameter</a>. Taking the address of these functions does not give you a pointer to member function, but a pointer to function, following their semantics as being effectively non-member <code class="highlight"><c- k>friend</c-></code> functions:</p>
<pre class="language-c++ highlight"><c- n>template</c-> <c- o>&lt;</c-><c- kr>typename</c-> <c- n>T</c-><c- o>></c->
<c- k>struct</c-> <c- n>less_than</c-> <c- p>{</c->
    <c- b>bool</c-> <c- n>operator</c-><c- p>()(</c-><c- n>this</c-> <c- n>less_than</c-><c- p>,</c-> <c- n>T</c-> <c- k>const</c-><c- o>&amp;</c-><c- p>,</c-> <c- n>T</c-> <c- k>const</c-><c- o>&amp;</c-><c- p>);</c->
<c- p>};</c->
</pre>
   <p>The type of <code class="highlight"><c- o>&amp;</c-><c- n>less_than</c-><c- o>&lt;</c-><c- b>int</c-><c- o>>::</c-><c- k>operator</c-><c- p>()</c-></code> is <code class="highlight"><c- b>bool</c-><c- p>(</c-><c- o>*</c-><c- p>)(</c-><c- n>less_than</c-><c- o>&lt;</c-><c- b>int</c-><c- o>></c-><c- p>,</c-> <c- b>int</c-> <c- k>const</c-><c- o>&amp;</c-><c- p>,</c-> <c- b>int</c-> <c- k>const</c-><c- o>&amp;</c-><c- p>)</c-></code> and follows the usual rules of invocation:</p>
<pre class="language-c++ highlight"><c- n>less_than</c-><c- o>&lt;</c-><c- b>int</c-><c- o>></c-> <c- n>lt</c-><c- p>;</c->
<c- k>auto</c-> <c- n>p</c-> <c- o>=</c-> <c- o>&amp;</c-><c- n>less_than</c-><c- o>&lt;</c-><c- b>int</c-><c- o>>::</c-><c- n>operator</c-><c- p>();</c->

<c- n>lt</c-><c- p>(</c-><c- mi>1</c-><c- p>,</c-> <c- mi>2</c-><c- p>);</c->            <c- c1>// ok</c->
<c- n>p</c-><c- p>(</c-><c- n>lt</c-><c- p>,</c-> <c- mi>1</c-><c- p>,</c-> <c- mi>2</c-><c- p>);</c->         <c- c1>// ok</c->
<c- p>(</c-><c- n>lt</c-><c- p>.</c-><c- o>*</c-><c- n>p</c-><c- p>)(</c-><c- mi>1</c-><c- p>,</c-> <c- mi>2</c-><c- p>);</c->       <c- c1>// error: p is not a pointer to member function</c->
<c- n>invoke</c-><c- p>(</c-><c- n>p</c-><c- p>,</c-> <c- n>lt</c-><c- p>,</c-> <c- mi>1</c-><c- p>,</c-> <c- mi>2</c-><c- p>);</c-> <c- c1>// ok</c->
</pre>
   <h4 class="heading settled" data-level="3.2.6" id="pathological-cases"><span class="secno">3.2.6. </span><span class="content">Pathological cases</span><a class="self-link" href="#pathological-cases"></a></h4>
   <p>It is important to mention the pathological cases. First, what happens if <code class="highlight"><c- n>D</c-></code> is incomplete but becomes valid later?</p>
<pre class="language-cpp highlight"><c- k>struct</c-> <c- n>D</c-><c- p>;</c->
<c- k>struct</c-> <c- n>B</c-> <c- p>{</c->
    <c- b>void</c-> <c- n>foo</c-><c- p>(</c-><c- k>this</c-> <c- n>D</c-><c- o>&amp;</c-><c- p>);</c->
<c- p>};</c->
<c- k>struct</c-> <c- nl>D</c-> <c- p>:</c-> <c- n>B</c-> <c- p>{</c-> <c- p>};</c->
</pre>
   <p>Following the precedent of <a data-link-type="biblio" href="#biblio-p0929r2">[P0929R2]</a>, we think this should be fine, albeit strange. If <code class="highlight"><c- n>D</c-></code> is incomplete, we simply postpone checking until the point of call or formation of pointer to member, etc. At that point, the call will either not be viable or the formation of pointer-to-member would be ill-formed.</p>
   <p>For unrelated complete classes or non-classes:</p>
<pre class="language-cpp highlight"><c- k>struct</c-> <c- n>A</c-> <c- p>{</c-> <c- p>};</c->
<c- k>struct</c-> <c- n>B</c-> <c- p>{</c->
    <c- b>void</c-> <c- n>foo</c-><c- p>(</c-><c- k>this</c-> <c- n>A</c-><c- o>&amp;</c-><c- p>);</c->
    <c- b>void</c-> <c- nf>bar</c-><c- p>(</c-><c- k>this</c-> <c- b>int</c-><c- p>);</c->
<c- p>};</c->
</pre>
   <p>The declaration can be immediately diagnosed as ill-formed.</p>
   <p>Another interesting case, courtesy of Jens Maurer:</p>
<pre class="language-cpp highlight"><c- k>struct</c-> <c- n>D</c-><c- p>;</c->
<c- k>struct</c-> <c- n>B</c-> <c- p>{</c->
  <c- b>int</c-> <c- n>f1</c-><c- p>(</c-><c- k>this</c-> <c- n>D</c-><c- p>);</c->
<c- p>};</c->
<c- k>struct</c-> <c- nl>D1</c-> <c- p>:</c-> <c- n>B</c-> <c- p>{</c-> <c- p>};</c->
<c- k>struct</c-> <c- nl>D2</c-> <c- p>:</c-> <c- n>B</c-> <c- p>{</c-> <c- p>};</c->
<c- k>struct</c-> <c- nl>D</c-> <c- p>:</c-> <c- n>D1</c-><c- p>,</c-> <c- n>D2</c-> <c- p>{</c-> <c- p>};</c->

<c- b>int</c-> <c- n>x</c-> <c- o>=</c-> <c- n>D</c-><c- p>().</c-><c- n>f1</c-><c- p>();</c->  <c- c1>// error: ambiguous lookup</c->
<c- b>int</c-> <c- n>y</c-> <c- o>=</c-> <c- n>B</c-><c- p>().</c-><c- n>f1</c-><c- p>();</c->  <c- c1>// error: B is not implicitly convertible to D</c->
<c- k>auto</c-> <c- n>z</c-> <c- o>=</c-> <c- o>&amp;</c-><c- n>B</c-><c- o>::</c-><c- n>f1</c-><c- p>;</c->   <c- c1>// ok</c->
<c- n>z</c-><c- p>(</c-><c- n>D</c-><c- p>());</c->            <c- c1>// ok</c->
</pre>
   <p>Even though both <code class="highlight"><c- n>D</c-><c- p>().</c-><c- n>f1</c-><c- p>()</c-></code> and <code class="highlight"><c- n>B</c-><c- p>().</c-><c- n>f1</c-><c- p>()</c-></code> are ill-formed, for entirely different reasons, taking a pointer to <code class="highlight"><c- o>&amp;</c-><c- n>B</c-><c- o>::</c-><c- n>f1</c-></code> is acceptable — its type is <code class="highlight"><c- b>int</c-><c- p>(</c-><c- o>*</c-><c- p>)(</c-><c- n>D</c-><c- p>)</c-></code> — and that function pointer can be invoked with a <code class="highlight"><c- n>D</c-></code>. Actually invoking this function does not require any further name lookup or conversion because by-value member functions do not have an implicit object parameter in this syntax (see <a href="#by-value-this">§3.2.3 By value this</a>).</p>
   <h4 class="heading settled" data-level="3.2.7" id="teachability-implications"><span class="secno">3.2.7. </span><span class="content">Teachability Implications</span><a class="self-link" href="#teachability-implications"></a></h4>
   <p>Explicitly naming the object as the <code class="highlight"><c- k>this</c-></code>-designated first parameter fits within many programmers' mental models of the <code class="highlight"><c- k>this</c-></code> pointer being the first parameter to member functions "under the hood" and is comparable to its usage in other languages, e.g. Python and Rust. It also works as a more obvious way to teach how <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>bind</c-></code>, <code class="highlight"><c- n>std</c-><c- o>::</c-><c- kr>thread</c-></code>, <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>function</c-></code>, and others work with a member function pointer by making the pointer explicit.</p>
   <p>A natural extension of having trailing <em>cv-</em> and <em>ref-qualifiers</em> to non-static member functions is providing an explicit type to which those qualifiers refer in place of the implied class type. This keeps all of the qualifiers together, which is more idiomatic C++ in this sense. The ability to deduce this type follows once we have somewhere we can name it.</p>
   <p>We do not believe there to be any teachability problems with either choice of syntax.</p>
   <h4 class="heading settled" data-level="3.2.8" id="static-member-functions"><span class="secno">3.2.8. </span><span class="content">Can <code class="highlight"><c- k>static</c-></code> member functions have an explicit object type?</span><a class="self-link" href="#static-member-functions"></a></h4>
   <p>No. Static member functions currently do not have an implicit object parameter, and therefore have no reason to provide an explicit one.</p>
   <h4 class="heading settled" data-level="3.2.9" id="interplays-with-capturing-this"><span class="secno">3.2.9. </span><span class="content">Interplays with capturing <code class="highlight"><c- p>[</c-><c- k>this</c-><c- p>]</c-></code> and <code class="highlight"><c- p>[</c-><c- o>*</c-><c- k>this</c-><c- p>]</c-></code> in lambdas</span><a class="self-link" href="#interplays-with-capturing-this"></a></h4>
   <p>Impacts differ depending on the chosen syntax.</p>
   <h5 class="heading settled" data-level="3.2.9.1" id="capture-this-with-id"><span class="secno">3.2.9.1. </span><span class="content">Syntaxes with an identifier</span><a class="self-link" href="#capture-this-with-id"></a></h5>
   <p>For <a href="#syntax-1">§3.1.1 Explicit this-annotated parameter</a> and <a href="#syntax-3">§3.1.3 Trailing type with identifier</a>, interoperability is perfect, since they do not impact the meaning of <code class="highlight"><c- k>this</c-></code> in a function body. The introduced identifier <code class="highlight"><c- n>self</c-></code> can then be used to refer to the lambda instance from the body.</p>
   <h5 class="heading settled" data-level="3.2.9.2" id="capture-this-no-id"><span class="secno">3.2.9.2. </span><span class="content">Syntaxes without an identifier</span><a class="self-link" href="#capture-this-no-id"></a></h5>
   <p>For <a href="#syntax-2">§3.1.2 Explicit this parameter</a> and <a href="#syntax-4">§3.1.4 Trailing type sans identifier</a>, things get more complex, since they use <code class="highlight"><c- k>this</c-></code> for their own purposes.</p>
   <p>The sensible meaning differs between <a href="#syntax-2">§3.1.2 Explicit this parameter</a> and <a href="#syntax-4">§3.1.4 Trailing type sans identifier</a>, since they introduce their parameters in different ways.</p>
   <p>With <a href="#syntax-2">§3.1.2 Explicit this parameter</a>, <code class="highlight"><c- k>this</c-></code> is a parameter of the implied type. Parameters shadow closure members, so <code class="highlight"><c- k>this</c-></code> should as well, making the capture of <code class="highlight"><c- k>this</c-></code> in lambdas <em>a lot</em> less powerful. One possible solution is to allow explicit referencing of closure members in this case so that <code class="highlight"><c- k>this</c-><c- p>.</c-><c- k>this</c-></code> becomes the captured <code class="highlight"><c- k>this</c-></code> object.</p>
   <p>With <a href="#syntax-4">§3.1.4 Trailing type sans identifier</a>, behavior must stay the same, meaning that there is no possible way to refer to the lambda object. This effectively prohibits <a href="#syntax-4">§3.1.4 Trailing type sans identifier</a> from solving the recursive lambda problem. The rules for what <code class="highlight"><c- k>this</c-></code> means in a lambda today still apply: <code class="highlight"><c- k>this</c-></code> can only ever refer to a captured member pointer of an outer member function, and can never be a pointer to the lambda instance itself.</p>
<pre class="language-cpp highlight"><c- k>struct</c-> <c- n>X</c-> <c- p>{</c->
    <c- b>int</c-> <c- n>x</c-><c- p>,</c-> <c- n>y</c-><c- p>;</c->

    <c- k>auto</c-> <c- nf>getter</c-><c- p>()</c-> <c- k>const</c->
    <c- p>{</c->
        <c- k>return</c-> <c- p>[</c-><c- o>*</c-><c- k>this</c-><c- p>]</c-><c- o>&lt;</c-><c- k>typename</c-> <c- n>Self</c-><c- o>></c-><c- p>()</c-> <c- n>Self</c-><c- o>&amp;&amp;</c-> <c- p>{</c->
            <c- k>return</c-> <c- n>x</c->       <c- c1>// still refers to X::x</c->
                <c- o>+</c-> <c- k>this</c-><c- o>-></c-><c- n>y</c-><c- p>;</c-> <c- c1>// still refers to X::y</c->
        <c- p>};</c->
    <c- p>}</c->
<c- p>};</c->
</pre>
   <h4 class="heading settled" data-level="3.2.10" id="parsing-issues"><span class="secno">3.2.10. </span><span class="content">Parsing issues</span><a class="self-link" href="#parsing-issues"></a></h4>
   <p>The object parameter syntaxes (<a href="#syntax-1">§3.1.1 Explicit this-annotated parameter</a> and <a href="#syntax-2">§3.1.2 Explicit this parameter</a>) have no parsing issues that we are aware of.</p>
   <p>With the addition of a new type name after the <em>parameter-declaration-clause</em> (in <a href="#syntax-3">§3.1.3 Trailing type with identifier</a> and <a href="#syntax-4">§3.1.4 Trailing type sans identifier</a>), we potentially run into a clash with the existing <em>virt-specifier</em>s, especially if allowing for an arbitrary identifier.</p>
   <p>Consider:</p>
<pre class="language-cpp highlight"><c- k>struct</c-> <c- n>B</c-> <c- p>{</c->
    <c- k>virtual</c-> <c- n>B</c-><c- o>*</c-> <c- k>override</c-><c- p>()</c-> <c- o>=</c-> <c- mi>0</c-><c- p>;</c->
<c- p>};</c->

<c- k>struct</c-> <c- k>override</c-> <c- o>:</c-> <c- n>B</c-> <c- p>{</c->
    <c- k>override</c-><c- o>*</c-> <c- k>override</c-><c- p>()</c-> <c- k>override</c-> <c- k>override</c-> <c- k>override</c-><c- p>;</c-> <c- c1>// #1</c->
    <c- k>override</c-><c- o>*</c-> <c- nf>override</c-><c- p>()</c-> <c- k>override</c-> <c- k>override</c-><c- p>;</c->          <c- c1>// #2</c->
    <c- k>override</c-><c- o>*</c-> <c- nf>override</c-><c- p>()</c-> <c- k>override</c-><c- p>;</c->                   <c- c1>// #3</c->
    <c- k>override</c-><c- o>*</c-> <c- nf>override</c-><c- p>();</c->                            <c- c1>// #4</c->
<c- p>};</c->
</pre>
   <p>The same problem would occur with <code class="highlight"><c- k>final</c-></code>.</p>
   <p>In order to disambiguate between a trailing object type, a trailing arbitrary identifier, and a <em>virt-specifier</em> — or any future trailing context-sensitive keyword — we would have to specify a preference, which would probably be to parse out the type first and the identifier second, assuming an identifier is allowed.</p>
   <p>If we go with syntax that allows for an identifier, <code class="highlight"><c- cp>#1</c-></code> will have an explicit object of type <code class="highlight"><c- k>override</c-></code> named <code class="highlight"><c- k>override</c-></code> that is an <code class="highlight"><c- k>override</c-></code>. <code class="highlight"><c- cp>#2</c-></code> would declare an object with an identifier that does not make use of the override <em>virt-specifier</em>. <code class="highlight"><c- cp>#3</c-></code> would provide an explicit object type without an identifier. Notably, <code class="highlight"><c- cp>#3</c-></code> is valid code even today, and would remain valid code. Only the meaning of the <code class="highlight"><c- k>override</c-></code> identifier would change.</p>
   <p>If we go with syntax that does <em>not</em> allow for an identifier, <code class="highlight"><c- cp>#1</c-></code> would be ill-formed, <code class="highlight"><c- cp>#2</c-></code> would declare an explicit object having type <code class="highlight"><c- k>override</c-></code> that has the <em>virt-specifier</em> <code class="highlight"><c- k>override</c-></code>, and <code class="highlight"><c- cp>#3</c-></code> would likewise change meaning.</p>
   <p>In practice, we do not believe that anybody actually writes code like this, so it is unlikely to break real code.</p>
   <p>We feel that allowing for an arbitrary identifier would be grabbing too much real estate with minimal benefit, as it would constrain further evolution of the standard and make it more difficult to use. Let’s say we added a new context-sensitive keyword, like <code class="highlight"><c- n>super</c-></code>. A user might try to write:</p>
<pre class="language-cpp highlight"><c- k>struct</c-> <c- n>Y</c-> <c- p>{</c->
    <c- c1>// intending to use the new context-sensitive keyword but</c->
    <c- c1>// really is providing a name to the object parameter?</c->
    <c- b>void</c-> <c- n>a</c-><c- p>()</c-> <c- n>super</c-><c- p>;</c->
    
    <c- c1>// same</c->
    <c- b>void</c-> <c- nf>b</c-><c- p>()</c-> <c- n>Y</c-> <c- n>super</c-><c- p>;</c->
    
    <c- c1>// okay, these finally use the keyword as desired - the user</c->
    <c- c1>// has to provide an identifier, even if they don’t want one</c->
    <c- b>void</c-> <c- nf>c</c-><c- p>()</c-> <c- n>_</c-> <c- n>super</c-><c- p>;</c->
    <c- b>void</c-> <c- nf>d</c-><c- p>()</c-> <c- n>Y</c-> <c- n>_</c-> <c- n>super</c-><c- p>;</c->
<c- p>};</c->
</pre>
   <p>Without an arbitrary identifier, <code class="highlight"><c- n>a</c-><c- p>()</c-></code> and <code class="highlight"><c- n>b</c-><c- p>()</c-></code> both treat <code class="highlight"><c- n>super</c-></code> as the context-sensitive keyword, as likely intended. The only edge case would be in a scenario where you have a type named <code class="highlight"><c- n>super</c-></code>.</p>
   <p>Now consider the following:</p>
<pre class="language-cpp highlight"><c- k>struct</c-> <c- n>Z</c-> <c- p>{</c->
    <c- b>void</c-> <c- n>foo</c-><c- p>()</c-> <c- n>cosnt</c-><c- p>;</c->
<c- p>};</c->
</pre>
   <p>The user made a typo and wrote <code class="highlight"><c- n>cosnt</c-></code> instead of <code class="highlight"><c- k>const</c-></code>. In C++17, it’s not a problem — this is ill-formed and the compiler will helpfully point out your problem.</p>
   <p>But if we allow an arbitrary trailing identifier and try to parse an identifier, even without an explicit type, this suddenly becomes well-formed. We declare a member function with an explicit object type that is implicitly <code class="highlight"><c- n>Z</c-></code>, and that explicit object is named <code class="highlight"><c- n>cosnt</c-></code>. Notably, this member function is <em>not</em> const!</p>
   <p>We may end up needing parsing rules, such as:</p>
   <ol>
    <li data-md>
     <p>Try to parse the type.</p>
    <li data-md>
     <p>If we find a type, then try to parse an identifier.</p>
    <li data-md>
     <p>Only then, consider things like the <em>virt-specifier</em>s.</p>
   </ol>
   <p>That’s complicated, to say the least. It also doesn’t quite mesh with the mental model a user might form about what this syntax means — that we have an implicitly-provided object type which is the class type:</p>
<pre class="language-c++ highlight"><c- k>struct</c-> <c- n>C</c-> <c- p>{</c->
    <c- b>void</c-> <c- n>foo</c-><c- p>();</c->   <c- c1>// implicit</c->
    <c- b>void</c-> <c- nf>foo</c-><c- p>()</c-> <c- n>C</c-><c- p>;</c-> <c- c1>// explicit</c->
    
    <c- b>void</c-> <c- nf>bar</c-><c- p>()</c-> <c- k>const</c-><c- o>&amp;</c-><c- p>;</c->   <c- c1>// implicit</c->
    <c- b>void</c-> <c- nf>bar</c-><c- p>()</c-> <c- n>C</c-> <c- k>const</c-><c- o>&amp;</c-><c- p>;</c-> <c- c1>// explicit</c->
    
    <c- c1>// so it seems like it should follow that...</c->
    <c- b>void</c-> <c- nf>quux</c-><c- p>()</c-> <c- n>self</c-><c- p>;</c->          <c- c1>// implicit</c->
    <c- b>void</c-> <c- nf>quux</c-><c- p>()</c-> <c- n>C</c-> <c- n>self</c-><c- p>;</c->        <c- c1>// explicit</c->
    
    <c- b>void</c-> <c- nf>quuz</c-><c- p>()</c-> <c- k>const</c-><c- o>&amp;</c-> <c- n>self</c-><c- p>;</c->   <c- c1>// implicit</c->
    <c- b>void</c-> <c- nf>quuz</c-><c- p>()</c-> <c- n>C</c-> <c- k>const</c-><c- o>&amp;</c-> <c- n>self</c-><c- p>;</c-> <c- c1>// explicit</c->
<c- p>};</c->
</pre>
   <p>Either the <code class="highlight"><c- n>quux</c-></code> or <code class="highlight"><c- n>quuz</c-></code> examples fail by making the implicit versions ill-formed, or we end up with this <code class="highlight"><c- n>cosnt</c-></code> typo problem. Neither option is desirable.</p>
   <h3 class="heading settled" data-level="3.3" id="comparison"><span class="secno">3.3. </span><span class="content">Comparison of the options</span><a class="self-link" href="#comparison"></a></h3>
   <p>Here is a comparison of the four main syntaxes against a variety of metrics:</p>
   <table>
    <tbody>
     <tr>
      <th style="width: 8%;">
      <th style="width: 20%;"><a href="#syntax-1">§3.1.1 Explicit this-annotated parameter</a>
      <th style="width: 18%;"><a href="#syntax-2">§3.1.2 Explicit this parameter</a>
      <th style="width: 20%;"><a href="#syntax-3">§3.1.3 Trailing type with identifier</a>
      <th style="width: 20%;"><a href="#syntax-4">§3.1.4 Trailing type sans identifier</a>
     <tr>
      <th>Familiarity
      <td>Novel to C++, familiar to users of other languages. Adds an additional way to define <em>cv</em>- and <em>ref</em> qualifiers.
      <td>Same unfamiliarity as at-left; <code class="highlight"><c- k>this</c-></code> behaves consistently with its declaration.
      <td colspan="2">Keeps <em>cv</em>- and <em>ref</em>-qualifiers where they already are, so it is a natural extension.
     <tr>
      <th>Safety with derived objects<sup>†</sup>
      <td>Easy, if <code class="highlight"><c- k>this</c-></code> is accessible; verbose otherwise. 
      <td>Difficult and verbose. 
      <td>Easy, if <code class="highlight"><c- k>this</c-></code> is accessible; verbose otherwise. 
      <td>Verbose.
     <tr>
      <th>Parsing issues
      <td>None
      <td>None
      <td>Definite problems requiring a choice of parsing strategy. Limits further extensions with context-sensitive keywords.
      <td>Some problems.
     <tr>
      <th>Code bloat<sup>‡</sup>
      <td colspan="2">Cannot deduce <code class="highlight"><c- k>const</c-></code>/non-<code class="highlight"><c- k>const</c-></code>, so would usually have to resort to <code class="highlight"><c- n>Self</c-><c- o>&amp;&amp;</c-></code>.
      <td>Not an issue.
      <td>Not an issue.
   </table>
   <p><sup>†</sup><em>Safety with derived objects</em>: the simplicity of writing member functions that want to deduce <em>cv-qualifiers</em> and value category without inadvertently referencing a shadowing member of the derived object. This table assumes we do not adopt the <a href="#potential-extensions">§3.4 Potential Extension</a>. Syntaxes that do not introduce an identifier (<a href="#syntax-2">§3.1.2 Explicit this parameter</a> and <a href="#syntax-4">§3.1.4 Trailing type sans identifier</a>) have no way of providing a non-verbose way of referring to members of the base class, and are therefore marked as "Verbose".</p>
   <p><sup>‡</sup>Code bloat, in this context, means that we have to determine whether we must produce more instantiations than would be minimally necessary to solve the problem. Deferring to a templated implementation is an acceptable option and has been improved by no longer requiring casts. The problem is minimal.</p>
   <h4 class="heading settled" data-level="3.3.1" id="use-case-table"><span class="secno">3.3.1. </span><span class="content">Use-case analysis</span><a class="self-link" href="#use-case-table"></a></h4>
   <p>We evaluated how well the various syntax options work for the various use-cases they are meant to solve:</p>
   <table>
    <tbody>
     <tr>
      <th>
      <th><a href="#syntax-1">§3.1.1 Explicit this-annotated parameter</a>
      <th><a href="#syntax-2">§3.1.2 Explicit this parameter</a>
      <th><a href="#syntax-3">§3.1.3 Trailing type with identifier</a>
      <th><a href="#syntax-4">§3.1.4 Trailing type sans identifier</a>
     <tr>
      <th><a href="#deduplicating-code">§4.1 Deduplicating Code</a>
      <td>
       <div class="ins">
        <center>Yes</center>
       </div>
      <td>
       <div class="ins">
        <center>Yes</center>
       </div>
      <td>
       <div class="ins">
        <center>Yes</center>
       </div>
      <td>
       <div class="ins">
        <center>Yes</center>
       </div>
     <tr>
      <th><a href="#crtp">§4.2 CRTP, without the C, R, or even T</a>
      <td>
       <div class="ins">
        <center>Yes</center>
       </div>
      <td>
       <div class="ins">
        <center>Yes</center>
       </div>
      <td>
       <div class="ins">
        <center>Yes</center>
       </div>
      <td>
       <div class="ins">
        <center>Yes</center>
       </div>
     <tr>
      <th><a href="#recursive-lambdas">§4.3 Recursive Lambdas</a>
      <td>
       <div class="ins">
        <center>Yes</center>
       </div>
      <td>
       <div class="ins">
        <center>Yes†</center>
       </div>
      <td>
       <div class="ins">
        <center>Yes</center>
       </div>
      <td>
       <div class="del">
        <center>No</center>
       </div>
     <tr>
      <th><a href="#by-value-member-functions">§4.4 By-value member functions</a>
      <td>
       <div class="ins">
        <center>Yes</center>
       </div>
      <td>
       <div class="ins">
        <center>Yes</center>
       </div>
      <td>
       <div class="del">
        <center>No</center>
       </div>
      <td>
       <div class="del">
        <center>No</center>
       </div>
     <tr>
      <th><a href="#sfinae-friendly-callables">§4.5 SFINAE-friendly callables</a>
      <td>
       <div class="ins">
        <center>Yes</center>
       </div>
      <td>
       <div class="ins">
        <center>Yes</center>
       </div>
      <td>
       <div class="ins">
        <center>Yes</center>
       </div>
      <td>
       <div class="ins">
        <center>Yes</center>
       </div>
   </table>
   <p>† While both <a href="#syntax-1">§3.1.1 Explicit this-annotated parameter</a> and <a href="#syntax-2">§3.1.2 Explicit this parameter</a> support recursive lambdas, nestedly-recursive lambdas are easier if one can assign an identifier in a natural way. <a href="#syntax-2">§3.1.2 Explicit this parameter</a> also has unwelcome interactions with capturing <code class="highlight"><c- k>this</c-></code> in the lambda, since the parameter <code class="highlight"><c- k>this</c-></code> must shadow the captured one.</p>
   <h3 class="heading settled" data-level="3.4" id="potential-extensions"><span class="secno">3.4. </span><span class="content">Potential Extension</span><a class="self-link" href="#potential-extensions"></a></h3>
   <p>This extension is not explicitly proposed proposed by our paper, since it has not yet been completely explored. Nevertheless, the authors believe that certain concerns raised by the proposed feature may be alleviated by discussing the following possible solution to those issues.</p>
   <p>One of the pitfalls of having a deduced object parameter or a deduced trailing object type is when the intent is solely to deduce the <em>cv</em>-qualifiers and value category of the object parameter, but a derived type is deduced as well — any access through an object that might have a derived type could inadvertently refer to a shadowed member in the derived class. While this is desirable and very powerful in the case of mixins, it is not always desirable in other situations. Superfluous template instantiations are also unwelcome side effects.</p>
   <p>One family of possible solutions could be summarized as <strong>make it easy to get the base class pointer</strong>. However, all of these solutions still require extra instantiations. For <code class="highlight"><c- n>optional</c-><c- o>::</c-><c- n>value</c-><c- p>()</c-></code>, we really only want four instantiations: <code class="highlight"><c- o>&amp;</c-></code>, <code class="highlight"><c- k>const</c-><c- o>&amp;</c-></code>, <code class="highlight"><c- o>&amp;&amp;</c-></code>, and <code class="highlight"><c- k>const</c-><c- o>&amp;&amp;</c-></code>. If something inherits from <code class="highlight"><c- n>optional</c-></code>, we don’t want additional instantiations of those functions for the derived types, which won’t do anything new, anyway. This is code bloat.</p>
   <p>C++ already has this long-recognised problem for free function templates. The authors have heard many a complaint about it from library vendors, even before this paper was introduced, as it is desirable to only deduce the ref-qualifier in many contexts. Therefore, it might make sense to tackle this issue in a more general way. A complementary feature could be proposed to constrain <em>type deduction</em> as opposed to removing candidates once they are deduced (as accomplished by <code class="highlight"><c- n>requires</c-></code>), with the following straw-man syntax:</p>
<pre class="language-cpp highlight"><c- k>struct</c-> <c- n>Base</c-> <c- p>{</c->
    <c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-> <c- nl>Self</c-> <c- p>:</c-> <c- n>Base</c-><c- o>></c->
    <c- k>auto</c-> <c- n>front</c-><c- p>(</c-><c- k>this</c-> <c- n>Self</c-><c- o>&amp;&amp;</c-> <c- n>self</c-><c- p>);</c->
<c- p>};</c->
<c- k>struct</c-> <c- nl>Derived</c-> <c- p>:</c-> <c- n>Base</c-> <c- p>{</c-> <c- p>};</c->

<c- c1>// also works for free functions</c->
<c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-> <c- nl>T</c-> <c- p>:</c-> <c- n>Base</c-><c- o>></c->
<c- b>void</c-> <c- n>foo</c-><c- p>(</c-><c- n>T</c-><c- o>&amp;&amp;</c-> <c- n>x</c-><c- p>)</c-> <c- p>{</c->
   <c- k>static_assert</c-><c- p>(</c-><c- n>is_same_v</c-><c- o>&lt;</c-><c- n>Base</c-><c- p>,</c-> <c- n>remove_reference_t</c-><c- o>&lt;</c-><c- n>T</c-><c- o>>></c-><c- p>);</c->
<c- p>}</c->

<c- n>Base</c-><c- p>{}.</c-><c- n>front</c-><c- p>();</c-> <c- c1>// calls Base::front&lt;Base></c->
<c- n>Derived</c-><c- p>{}.</c-><c- n>front</c-><c- p>();</c-> <c- c1>// also calls Base::front&lt;Base></c->

<c- n>foo</c-><c- p>(</c-><c- n>Base</c-><c- p>{});</c-> <c- c1>// calls foo&lt;Base></c->
<c- n>foo</c-><c- p>(</c-><c- n>Derived</c-><c- p>{});</c-> <c- c1>// also calls foo&lt;Base></c->
</pre>
   <p>This would create a function template that only generates functions taking a <code class="highlight"><c- n>Base</c-></code>, ensuring that we don’t generate additional instantiations when those functions participate in overload resolution. Such a proposal would also change how templates participate in overload resolution, however, and is not to be attempted haphazardly.</p>
   <h2 class="heading settled" data-level="4" id="real-world-examples"><span class="secno">4. </span><span class="content">Real-World Examples</span><a class="self-link" href="#real-world-examples"></a></h2>
   <p>What follows are several examples of the kinds of problems that can be solved using this proposal. We provide examples using two different syntaxes, where possible:</p>
   <ul>
    <li data-md>
     <p>the explicit object parameter syntax, with <code class="highlight"><c- k>this</c-></code> accessible but implicit lookup disallowed; and</p>
    <li data-md>
     <p>the explicit object type syntax, with no identifier allowed.</p>
   </ul>
   <p>We are not using the straw-man <a href="#potential-extensions">extension</a> syntax to constrain deduction. Instead, we just carefully ensure correctness, where relevant.</p>
   <h3 class="heading settled" data-level="4.1" id="deduplicating-code"><span class="secno">4.1. </span><span class="content">Deduplicating Code</span><a class="self-link" href="#deduplicating-code"></a></h3>
   <p>This proposal can de-duplicate and de-quadruplicate a large amount of code. In each case, the single function is only slightly more complex than the initial two or four, which makes for a huge win. What follows are a few examples of ways to reduce repeated code.</p>
   <p>This particular implementation of optional is Simon’s, and can be viewed on <a href="https://github.com/TartanLlama/optional">GitHub</a>. It includes some functions proposed in <a data-link-type="biblio" href="#biblio-p0798r0">[P0798R0]</a>, with minor changes to better suit this format:</p>
   <table style="width:100%">
    <tbody>
     <tr>
      <th style="width:33%">C++17
      <th style="width:33%"><a href="#syntax-1">§3.1.1 Explicit this-annotated parameter</a>
      <th style="width:33%"><a href="#syntax-4">§3.1.4 Trailing type sans identifier</a>
     <tr>
      <td>
<pre class="language-cpp highlight"><c- k>class</c-> <c- nc>TextBlock</c-> <c- p>{</c->
<c- k>public</c-><c- o>:</c->
  <c- b>char</c-> <c- k>const</c-><c- o>&amp;</c-> <c- k>operator</c-><c- p>[](</c-><c- b>size_t</c-> <c- n>position</c-><c- p>)</c-> <c- k>const</c-> <c- p>{</c->
    <c- c1>// ...</c->
    <c- k>return</c-> <c- n>text</c-><c- p>[</c-><c- n>position</c-><c- p>];</c->
  <c- p>}</c->

  <c- b>char</c-><c- o>&amp;</c-> <c- k>operator</c-><c- p>[](</c-><c- b>size_t</c-> <c- n>position</c-><c- p>)</c-> <c- p>{</c->
    <c- k>return</c-> <c- k>const_cast</c-><c- o>&lt;</c-><c- b>char</c-><c- o>&amp;></c-><c- p>(</c->
      <c- k>static_cast</c-><c- o>&lt;</c-><c- n>TextBlock</c-> <c- k>const</c-><c- o>&amp;></c->
        <c- p>(</c-><c- k>this</c-><c- p>)[</c-><c- n>position</c-><c- p>]</c->
    <c- p>);</c->
  <c- p>}</c->
  <c- c1>// ...</c->
<c- p>};</c->
</pre>
      <td>
<pre class="language-cpp highlight"><c- k>class</c-> <c- nc>TextBlock</c-> <c- p>{</c->
<c- k>public</c-><c- o>:</c->
  <c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-> <c- n>Self</c-><c- o>></c->
  <c- k>auto</c-><c- o>&amp;</c-> <c- k>operator</c-><c- p>[](</c-><c- k>this</c-> <c- n>Self</c-><c- o>&amp;&amp;</c-><c- p>,</c-> <c- b>size_t</c-> <c- n>position</c-><c- p>)</c-> <c- p>{</c->
    <c- c1>// ...</c->
    <c- k>return</c-> <c- k>this</c-><c- o>-></c-><c- n>text</c-><c- p>[</c-><c- n>position</c-><c- p>];</c->
  <c- p>}</c->
  <c- c1>// ...</c->
<c- p>};</c->
</pre>
      <td>
<pre class="language-cpp highlight"><c- k>class</c-> <c- nc>TextBlock</c-> <c- p>{</c->
<c- k>public</c-><c- o>:</c->
  <c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-> <c- n>Self</c-><c- o>></c->
  <c- k>auto</c-><c- o>&amp;</c-> <c- k>operator</c-><c- p>[](</c-><c- b>size_t</c-> <c- n>position</c-><c- p>)</c-> <c- n>Self</c-> <c- p>{</c->
    <c- c1>// ...</c->
    <c- k>return</c-> <c- k>this</c-><c- o>-></c-><c- n>TextBlock</c-><c- o>::</c-><c- n>text</c-><c- p>[</c-><c- n>position</c-><c- p>];</c->
  <c- p>}</c->
  <c- c1>// ...</c->
<c- p>};</c->
</pre>
     <tr>
      <td>
<pre class="language-cpp highlight"><c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-> <c- n>T</c-><c- o>></c->
<c- k>class</c-> <c- nc>optional</c-> <c- p>{</c->
  <c- c1>// ...</c->
  <c- k>constexpr</c-> <c- n>T</c-><c- o>*</c-> <c- k>operator</c-><c- o>-></c-><c- p>()</c-> <c- p>{</c->
    <c- k>return</c-> <c- n>addressof</c-><c- p>(</c-><c- k>this</c-><c- o>-></c-><c- n>m_value</c-><c- p>);</c->
  <c- p>}</c->

  <c- k>constexpr</c-> <c- n>T</c-> <c- k>const</c-><c- o>*</c->
  <c- k>operator</c-><c- o>-></c-><c- p>()</c-> <c- k>const</c-> <c- p>{</c->
    <c- k>return</c-> <c- n>addressof</c-><c- p>(</c-><c- k>this</c-><c- o>-></c-><c- n>m_value</c-><c- p>);</c->
  <c- p>}</c->
  <c- c1>// ...</c->
<c- p>};</c->
</pre>
      <td>
<pre class="language-cpp highlight"><c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-> <c- n>T</c-><c- o>></c->
<c- k>class</c-> <c- nc>optional</c-> <c- p>{</c->
  <c- c1>// ...</c->
  <c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-> <c- n>Self</c-><c- o>></c->
  <c- k>constexpr</c-> <c- k>auto</c-> <c- k>operator</c-><c- o>-></c-><c- p>(</c-><c- k>this</c-> <c- n>Self</c-><c- o>&amp;&amp;</c-><c- p>)</c-> <c- p>{</c->
    <c- k>return</c-> <c- n>addressof</c-><c- p>(</c-><c- k>this</c-><c- o>-></c-><c- n>m_value</c-><c- p>);</c->
  <c- p>}</c->
  <c- c1>// ...</c->
<c- p>};</c->
</pre>
      <td>
<pre class="language-cpp highlight"><c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-> <c- n>T</c-><c- o>></c->
<c- k>class</c-> <c- nc>optional</c-> <c- p>{</c->
  <c- c1>// ...</c->
  <c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-> <c- n>Self</c-><c- o>></c->
  <c- k>constexpr</c-> <c- k>auto</c-> <c- k>operator</c-><c- o>-></c-><c- p>()</c-> <c- n>Self</c-> <c- p>{</c->
    <c- k>return</c-> <c- n>addressof</c-><c- p>(</c-><c- k>this</c-><c- o>-></c-><c- n>optional</c-><c- o>::</c-><c- n>m_value</c-><c- p>);</c->
  <c- p>}</c->
  <c- c1>// ...</c->
<c- p>};</c->
</pre>
     <tr>
      <td>
<pre class="language-cpp highlight"><c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-> <c- n>T</c-><c- o>></c->
<c- k>class</c-> <c- nc>optional</c-> <c- p>{</c->
  <c- c1>// ...</c->
  <c- k>constexpr</c-> <c- n>T</c-><c- o>&amp;</c-> <c- k>operator</c-><c- o>*</c-><c- p>()</c-> <c- o>&amp;</c-> <c- p>{</c->
    <c- k>return</c-> <c- k>this</c-><c- o>-></c-><c- n>m_value</c-><c- p>;</c->
  <c- p>}</c->

  <c- k>constexpr</c-> <c- n>T</c-> <c- k>const</c-><c- o>&amp;</c-> <c- k>operator</c-><c- o>*</c-><c- p>()</c-> <c- k>const</c-><c- o>&amp;</c-> <c- p>{</c->
    <c- k>return</c-> <c- k>this</c-><c- o>-></c-><c- n>m_value</c-><c- p>;</c->
  <c- p>}</c->

  <c- k>constexpr</c-> <c- n>T</c-><c- o>&amp;&amp;</c-> <c- k>operator</c-><c- o>*</c-><c- p>()</c-> <c- o>&amp;&amp;</c-> <c- p>{</c->
    <c- k>return</c-> <c- n>move</c-><c- p>(</c-><c- k>this</c-><c- o>-></c-><c- n>m_value</c-><c- p>);</c->
  <c- p>}</c->

  <c- k>constexpr</c-> <c- n>T</c-> <c- k>const</c-><c- o>&amp;&amp;</c->
  <c- k>operator</c-><c- o>*</c-><c- p>()</c-> <c- k>const</c-><c- o>&amp;&amp;</c-> <c- p>{</c->
    <c- k>return</c-> <c- n>move</c-><c- p>(</c-><c- k>this</c-><c- o>-></c-><c- n>m_value</c-><c- p>);</c->
  <c- p>}</c->

  <c- k>constexpr</c-> <c- n>T</c-><c- o>&amp;</c-> <c- n>value</c-><c- p>()</c-> <c- o>&amp;</c-> <c- p>{</c->
    <c- k>if</c-> <c- p>(</c-><c- n>has_value</c-><c- p>())</c-> <c- p>{</c->
      <c- k>return</c-> <c- k>this</c-><c- o>-></c-><c- n>m_value</c-><c- p>;</c->
    <c- p>}</c->
    <c- k>throw</c-> <c- n>bad_optional_access</c-><c- p>();</c->
  <c- p>}</c->

  <c- k>constexpr</c-> <c- n>T</c-> <c- k>const</c-><c- o>&amp;</c-> <c- n>value</c-><c- p>()</c-> <c- k>const</c-><c- o>&amp;</c-> <c- p>{</c->
    <c- k>if</c-> <c- p>(</c-><c- n>has_value</c-><c- p>())</c-> <c- p>{</c->
      <c- k>return</c-> <c- k>this</c-><c- o>-></c-><c- n>m_value</c-><c- p>;</c->
    <c- p>}</c->
    <c- k>throw</c-> <c- n>bad_optional_access</c-><c- p>();</c->
  <c- p>}</c->

  <c- k>constexpr</c-> <c- n>T</c-><c- o>&amp;&amp;</c-> <c- n>value</c-><c- p>()</c-> <c- o>&amp;&amp;</c-> <c- p>{</c->
    <c- k>if</c-> <c- p>(</c-><c- n>has_value</c-><c- p>())</c-> <c- p>{</c->
      <c- k>return</c-> <c- n>move</c-><c- p>(</c-><c- k>this</c-><c- o>-></c-><c- n>m_value</c-><c- p>);</c->
    <c- p>}</c->
    <c- k>throw</c-> <c- n>bad_optional_access</c-><c- p>();</c->
  <c- p>}</c->

  <c- k>constexpr</c-> <c- n>T</c-> <c- k>const</c-><c- o>&amp;&amp;</c-> <c- n>value</c-><c- p>()</c-> <c- k>const</c-><c- o>&amp;&amp;</c-> <c- p>{</c->
    <c- k>if</c-> <c- p>(</c-><c- n>has_value</c-><c- p>())</c-> <c- p>{</c->
      <c- k>return</c-> <c- n>move</c-><c- p>(</c-><c- k>this</c-><c- o>-></c-><c- n>m_value</c-><c- p>);</c->
    <c- p>}</c->
    <c- k>throw</c-> <c- n>bad_optional_access</c-><c- p>();</c->
  <c- p>}</c->
  <c- c1>// ...</c->
<c- p>};</c->
</pre>
      <td>
<pre class="language-cpp highlight"><c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-> <c- n>T</c-><c- o>></c->
<c- k>class</c-> <c- nc>optional</c-> <c- p>{</c->
  <c- c1>// ...</c->
  <c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-> <c- n>Self</c-><c- o>></c->
  <c- k>constexpr</c-> <c- n>like_t</c-><c- o>&lt;</c-><c- n>Self</c-><c- p>,</c-> <c- n>T</c-><c- o>>&amp;&amp;</c-> <c- k>operator</c-><c- o>*</c-><c- p>(</c-><c- k>this</c-> <c- n>Self</c-><c- o>&amp;&amp;</c-><c- p>)</c-> <c- p>{</c->
    <c- k>return</c-> <c- n>forward_like</c-><c- o>&lt;</c-><c- n>Self</c-><c- o>></c-><c- p>(</c-><c- o>*</c-><c- k>this</c-><c- p>).</c-><c- n>m_value</c-><c- p>;</c->
  <c- p>}</c->

  <c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-> <c- n>Self</c-><c- o>></c->
  <c- k>constexpr</c-> <c- n>like_t</c-><c- o>&lt;</c-><c- n>Self</c-><c- p>,</c-> <c- n>T</c-><c- o>>&amp;&amp;</c-> <c- n>value</c-><c- p>(</c-><c- k>this</c-> <c- n>Self</c-><c- o>&amp;&amp;</c-><c- p>)</c-> <c- p>{</c->
    <c- k>if</c-> <c- p>(</c-><c- k>this</c-><c- o>-></c-><c- n>has_value</c-><c- p>())</c-> <c- p>{</c->
      <c- k>return</c-> <c- n>forward_like</c-><c- o>&lt;</c-><c- n>Self</c-><c- o>></c-><c- p>(</c-><c- o>*</c-><c- k>this</c-><c- p>).</c-><c- n>m_value</c-><c- p>);</c->
    <c- p>}</c->
    <c- k>throw</c-> <c- n>bad_optional_access</c-><c- p>();</c->
  <c- p>}</c->
  <c- c1>// ...</c->
<c- p>};</c->
</pre>
      <td>
<pre class="language-cpp highlight"><c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-> <c- n>T</c-><c- o>></c->
<c- k>class</c-> <c- nc>optional</c-> <c- p>{</c->
  <c- c1>// ...</c->
  <c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-> <c- n>Self</c-><c- o>></c->
  <c- k>constexpr</c-> <c- n>like_t</c-><c- o>&lt;</c-><c- n>Self</c-><c- p>,</c-> <c- n>T</c-><c- o>>&amp;&amp;</c-> <c- k>operator</c-><c- o>*</c-><c- p>()</c-> <c- n>Self</c-><c- o>&amp;&amp;</c-> <c- p>{</c->
    <c- k>return</c-> <c- n>forward</c-><c- o>&lt;</c-><c- n>Self</c-><c- o>></c-><c- p>(</c-><c- o>*</c-><c- k>this</c-><c- p>).</c-><c- n>optional</c-><c- o>::</c-><c- n>m_value</c-><c- p>;</c->
  <c- p>}</c->

  <c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-> <c- n>Self</c-><c- o>></c->
  <c- k>constexpr</c-> <c- n>like_t</c-><c- o>&lt;</c-><c- n>Self</c-><c- p>,</c-> <c- n>T</c-><c- o>>&amp;&amp;</c-> <c- n>value</c-><c- p>()</c-> <c- n>Self</c-><c- o>&amp;&amp;</c-> <c- p>{</c->
    <c- k>if</c-> <c- p>(</c-><c- k>this</c-><c- o>-></c-><c- n>optional</c-><c- o>::</c-><c- n>has_value</c-><c- p>())</c-> <c- p>{</c->
      <c- k>return</c-> <c- n>forward</c-><c- o>&lt;</c-><c- n>Self</c-><c- o>></c-><c- p>(</c-><c- o>*</c-><c- k>this</c-><c- p>).</c-><c- n>optional</c-><c- o>::</c-><c- n>m_value</c-><c- p>;</c->
    <c- p>}</c->
    <c- k>throw</c-> <c- n>bad_optional_access</c-><c- p>();</c->
  <c- p>}</c->
  <c- c1>// ...</c->
<c- p>};</c->
</pre>
     <tr>
      <td>
<pre class="language-cpp highlight"><c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-> <c- n>T</c-><c- o>></c->
<c- k>class</c-> <c- nc>optional</c-> <c- p>{</c->
  <c- c1>// ...</c->
  <c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-> <c- n>F</c-><c- o>></c->
  <c- k>constexpr</c-> <c- k>auto</c-> <c- n>and_then</c-><c- p>(</c-><c- n>F</c-><c- o>&amp;&amp;</c-> <c- n>f</c-><c- p>)</c-> <c- o>&amp;</c-> <c- p>{</c->
    <c- k>using</c-> <c- n>result</c-> <c- o>=</c->
      <c- n>invoke_result_t</c-><c- o>&lt;</c-><c- n>F</c-><c- p>,</c-> <c- n>T</c-><c- o>&amp;></c-><c- p>;</c->
    <c- k>static_assert</c-><c- p>(</c->
      <c- n>is_optional</c-><c- o>&lt;</c-><c- n>result</c-><c- o>>::</c-><c- n>value</c-><c- p>,</c->
      <c- s>"F must return an optional"</c-><c- p>);</c->

    <c- k>return</c-> <c- nf>has_value</c-><c- p>()</c->
        <c- o>?</c-> <c- n>invoke</c-><c- p>(</c-><c- n>forward</c-><c- o>&lt;</c-><c- n>F</c-><c- o>></c-><c- p>(</c-><c- n>f</c-><c- p>),</c-> <c- o>**</c-><c- k>this</c-><c- p>)</c->
        <c- o>:</c-> <c- n>nullopt</c-><c- p>;</c->
  <c- p>}</c->

  <c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-> <c- n>F</c-><c- o>></c->
  <c- k>constexpr</c-> <c- k>auto</c-> <c- n>and_then</c-><c- p>(</c-><c- n>F</c-><c- o>&amp;&amp;</c-> <c- n>f</c-><c- p>)</c-> <c- o>&amp;&amp;</c-> <c- p>{</c->
    <c- k>using</c-> <c- n>result</c-> <c- o>=</c->
      <c- n>invoke_result_t</c-><c- o>&lt;</c-><c- n>F</c-><c- p>,</c-> <c- n>T</c-><c- o>&amp;&amp;></c-><c- p>;</c->
    <c- k>static_assert</c-><c- p>(</c->
      <c- n>is_optional</c-><c- o>&lt;</c-><c- n>result</c-><c- o>>::</c-><c- n>value</c-><c- p>,</c->
      <c- s>"F must return an optional"</c-><c- p>);</c->

    <c- k>return</c-> <c- nf>has_value</c-><c- p>()</c->
        <c- o>?</c-> <c- n>invoke</c-><c- p>(</c-><c- n>forward</c-><c- o>&lt;</c-><c- n>F</c-><c- o>></c-><c- p>(</c-><c- n>f</c-><c- p>),</c->
                 <c- n>move</c-><c- p>(</c-><c- o>**</c-><c- k>this</c-><c- p>))</c->
        <c- o>:</c-> <c- n>nullopt</c-><c- p>;</c->
  <c- p>}</c->

  <c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-> <c- n>F</c-><c- o>></c->
  <c- k>constexpr</c-> <c- k>auto</c-> <c- n>and_then</c-><c- p>(</c-><c- n>F</c-><c- o>&amp;&amp;</c-> <c- n>f</c-><c- p>)</c-> <c- k>const</c-><c- o>&amp;</c-> <c- p>{</c->
    <c- k>using</c-> <c- n>result</c-> <c- o>=</c->
      <c- n>invoke_result_t</c-><c- o>&lt;</c-><c- n>F</c-><c- p>,</c-> <c- n>T</c-> <c- k>const</c-><c- o>&amp;></c-><c- p>;</c->
    <c- k>static_assert</c-><c- p>(</c->
      <c- n>is_optional</c-><c- o>&lt;</c-><c- n>result</c-><c- o>>::</c-><c- n>value</c-><c- p>,</c->
      <c- s>"F must return an optional"</c-><c- p>);</c->

    <c- k>return</c-> <c- nf>has_value</c-><c- p>()</c->
        <c- o>?</c-> <c- n>invoke</c-><c- p>(</c-><c- n>forward</c-><c- o>&lt;</c-><c- n>F</c-><c- o>></c-><c- p>(</c-><c- n>f</c-><c- p>),</c-> <c- o>**</c-><c- k>this</c-><c- p>)</c->
        <c- o>:</c-> <c- n>nullopt</c-><c- p>;</c->
  <c- p>}</c->

  <c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-> <c- n>F</c-><c- o>></c->
  <c- k>constexpr</c-> <c- k>auto</c-> <c- n>and_then</c-><c- p>(</c-><c- n>F</c-><c- o>&amp;&amp;</c-> <c- n>f</c-><c- p>)</c-> <c- k>const</c-><c- o>&amp;&amp;</c-> <c- p>{</c->
    <c- k>using</c-> <c- n>result</c-> <c- o>=</c->
      <c- n>invoke_result_t</c-><c- o>&lt;</c-><c- n>F</c-><c- p>,</c-> <c- n>T</c-> <c- k>const</c-><c- o>&amp;&amp;></c-><c- p>;</c->
    <c- k>static_assert</c-><c- p>(</c->
      <c- n>is_optional</c-><c- o>&lt;</c-><c- n>result</c-><c- o>>::</c-><c- n>value</c-><c- p>,</c->
      <c- s>"F must return an optional"</c-><c- p>);</c->

    <c- k>return</c-> <c- nf>has_value</c-><c- p>()</c->
        <c- o>?</c-> <c- n>invoke</c-><c- p>(</c-><c- n>forward</c-><c- o>&lt;</c-><c- n>F</c-><c- o>></c-><c- p>(</c-><c- n>f</c-><c- p>),</c->
                 <c- n>move</c-><c- p>(</c-><c- o>**</c-><c- k>this</c-><c- p>))</c->
        <c- o>:</c-> <c- n>nullopt</c-><c- p>;</c->
  <c- p>}</c->
  <c- c1>// ...</c->
<c- p>};</c->
</pre>
      <td>
<pre class="language-cpp highlight"><c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-> <c- n>T</c-><c- o>></c->
<c- k>class</c-> <c- nc>optional</c-> <c- p>{</c->
  <c- c1>// ...</c->
  <c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-> <c- n>Self</c-><c- p>,</c-> <c- k>typename</c-> <c- n>F</c-><c- o>></c->
  <c- k>constexpr</c-> <c- k>auto</c-> <c- n>and_then</c-><c- p>(</c-><c- k>this</c-> <c- n>Self</c-><c- o>&amp;&amp;</c-><c- p>,</c-> <c- n>F</c-><c- o>&amp;&amp;</c-> <c- n>f</c-><c- p>)</c-> <c- p>{</c->
    <c- k>using</c-> <c- n>val</c-> <c- o>=</c-> <c- k>decltype</c-><c- p>((</c->
        <c- n>forward_like</c-><c- o>&lt;</c-><c- n>Self</c-><c- o>></c-><c- p>(</c-><c- o>*</c-><c- k>this</c-><c- p>).</c-><c- n>m_value</c-><c- p>));</c->
    <c- k>using</c-> <c- n>result</c-> <c- o>=</c-> <c- n>invoke_result_t</c-><c- o>&lt;</c-><c- n>F</c-><c- p>,</c-> <c- n>val</c-><c- o>></c-><c- p>;</c->

    <c- k>static_assert</c-><c- p>(</c->
      <c- n>is_optional</c-><c- o>&lt;</c-><c- n>result</c-><c- o>>::</c-><c- n>value</c-><c- p>,</c->
      <c- s>"F must return an optional"</c-><c- p>);</c->

    <c- k>return</c-> <c- k>this</c-><c- o>-></c-><c- n>has_value</c-><c- p>()</c->
        <c- o>?</c-> <c- n>invoke</c-><c- p>(</c-><c- n>forward</c-><c- o>&lt;</c-><c- n>F</c-><c- o>></c-><c- p>(</c-><c- n>f</c-><c- p>),</c->
                 <c- n>forward_like</c-><c- o>&lt;</c-><c- n>Self</c-><c- o>></c-><c- p>(</c-><c- o>*</c-><c- k>this</c-><c- p>).</c-><c- n>m_value</c-><c- p>)</c->
        <c- o>:</c-> <c- n>nullopt</c-><c- p>;</c->
  <c- p>}</c->
  <c- c1>// ...</c->
<c- p>};</c->
</pre>
      <td>
<pre class="language-cpp highlight"><c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-> <c- n>T</c-><c- o>></c->
<c- k>class</c-> <c- nc>optional</c-> <c- p>{</c->
  <c- c1>// ...</c->
  <c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-> <c- n>Self</c-><c- p>,</c-> <c- k>typename</c-> <c- n>F</c-><c- o>></c->
  <c- k>constexpr</c-> <c- k>auto</c-> <c- n>and_then</c-><c- p>(</c-><c- n>F</c-><c- o>&amp;&amp;</c-> <c- n>f</c-><c- p>)</c-> <c- n>Self</c-><c- o>&amp;&amp;</c-> <c- p>{</c->
    <c- k>using</c-> <c- n>val</c-> <c- o>=</c-> <c- k>decltype</c-><c- p>((</c->
        <c- n>forward</c-><c- o>&lt;</c-><c- n>Self</c-><c- o>></c-><c- p>(</c-><c- o>*</c-><c- k>this</c-><c- p>).</c-><c- n>optional</c-><c- o>::</c-><c- n>m_value</c-><c- p>));</c->
    <c- k>using</c-> <c- n>result</c-> <c- o>=</c-> <c- n>invoke_result_t</c-><c- o>&lt;</c-><c- n>F</c-><c- p>,</c-> <c- n>val</c-><c- o>></c-><c- p>;</c->

    <c- k>static_assert</c-><c- p>(</c->
      <c- n>is_optional</c-><c- o>&lt;</c-><c- n>result</c-><c- o>>::</c-><c- n>value</c-><c- p>,</c->
      <c- s>"F must return an optional"</c-><c- p>);</c->

    <c- k>return</c-> <c- k>this</c-><c- o>-></c-><c- n>optional</c-><c- o>::</c-><c- n>has_value</c-><c- p>()</c->
        <c- o>?</c-> <c- n>invoke</c-><c- p>(</c-><c- n>forward</c-><c- o>&lt;</c-><c- n>F</c-><c- o>></c-><c- p>(</c-><c- n>f</c-><c- p>),</c->
                 <c- n>forward</c-><c- o>&lt;</c-><c- n>Self</c-><c- o>></c-><c- p>(</c-><c- o>*</c-><c- k>this</c-><c- p>).</c-><c- n>optional</c-><c- o>::</c-><c- n>m_value</c-><c- p>)</c->
        <c- o>:</c-> <c- n>nullopt</c-><c- p>;</c->
  <c- p>}</c->
  <c- c1>// ...</c->
<c- p>};</c->
</pre>
   </table>
   <p>There are a few more functions in P0798 responsible for this explosion of overloads, so the difference in both code and clarity is dramatic.</p>
   <p>For those that dislike returning auto in these cases, it is easy to write a metafunction matching the appropriate qualifiers from a type. It is certainly a better option than blindly copying and pasting code, hoping that the minor changes were made correctly in each case.</p>
   <h3 class="heading settled" data-level="4.2" id="crtp"><span class="secno">4.2. </span><span class="content">CRTP, without the C, R, or even T</span><a class="self-link" href="#crtp"></a></h3>
   <p>Today, a common design pattern is the Curiously Recurring Template Pattern. This implies passing the derived type as a template parameter to a base class template as a way of achieving static polymorphism. If we wanted to simply outsource implementing postfix incrementation to a base, we could use CRTP for that. But with explicit objects that already deduce to the derived objects, we don’t need any curious recurrence — we can use standard inheritance and let deduction do its thing. The base class doesn’t even need to be a template:</p>
   <table style="width:100%">
    <tbody>
     <tr>
      <th style="width:33%">C++17
      <th style="width:33%"><a href="#syntax-1">§3.1.1 Explicit this-annotated parameter</a>
      <th style="width:33%"><a href="#syntax-4">§3.1.4 Trailing type sans identifier</a>
     <tr>
      <td>
<pre class="language-cpp highlight"><c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-> <c- n>Derived</c-><c- o>></c->
<c- k>struct</c-> <c- n>add_postfix_increment</c-> <c- p>{</c->
    <c- n>Derived</c-> <c- k>operator</c-><c- o>++</c-><c- p>(</c-><c- b>int</c-><c- p>)</c-> <c- p>{</c->
        <c- k>auto</c-><c- o>&amp;</c-> <c- n>self</c-> <c- o>=</c-> <c- k>static_cast</c-><c- o>&lt;</c-><c- n>Derived</c-><c- o>&amp;></c-><c- p>(</c-><c- o>*</c-><c- k>this</c-><c- p>);</c->

        <c- n>Derived</c-> <c- nf>tmp</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>tmp</c-><c- p>;</c->
    <c- p>}</c->
<c- p>};</c->

<c- k>struct</c-> <c- nl>some_type</c-> <c- p>:</c-> <c- n>add_postfix_increment</c-><c- o>&lt;</c-><c- n>some_type</c-><c- o>></c-> <c- p>{</c->
    <c- n>some_type</c-><c- o>&amp;</c-> <c- k>operator</c-><c- o>++</c-><c- p>()</c-> <c- p>{</c-> <c- p>...</c-> <c- p>}</c->
<c- p>};</c->
</pre>
      <td>
<pre class="language-cpp highlight"><c- k>struct</c-> <c- n>add_postfix_increment</c-> <c- p>{</c->
    <c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-> <c- n>Self</c-><c- o>></c->
    <c- k>auto</c-> <c- k>operator</c-><c- o>++</c-><c- p>(</c-><c- k>this</c-> <c- n>Self</c-><c- o>&amp;&amp;</c-> <c- n>self</c-><c- p>,</c-> <c- b>int</c-><c- p>)</c-> <c- p>{</c->
        <c- k>auto</c-> <c- n>tmp</c-> <c- o>=</c-> <c- n>self</c-><c- p>;</c->
        <c- o>++</c-><c- n>self</c-><c- p>;</c->
        <c- k>return</c-> <c- n>tmp</c-><c- p>;</c->
    <c- p>}</c->
<c- p>};</c->



<c- k>struct</c-> <c- nl>some_type</c-> <c- p>:</c-> <c- n>add_postfix_increment</c-> <c- p>{</c->
    <c- n>some_type</c-><c- o>&amp;</c-> <c- k>operator</c-><c- o>++</c-><c- p>()</c-> <c- p>{</c-> <c- p>...</c-> <c- p>}</c->
<c- p>};</c->
</pre>
      <td>
<pre class="language-cpp highlight"><c- k>struct</c-> <c- n>add_postfix_increment</c-> <c- p>{</c->
    <c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-> <c- n>Self</c-><c- o>></c->
    <c- n>Self</c-> <c- k>operator</c-><c- o>++</c-><c- p>(</c-><c- b>int</c-><c- p>)</c-> <c- n>Self</c-> <c- p>{</c->
        <c- n>Self</c-> <c- n>tmp</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>tmp</c-><c- p>;</c->
    <c- p>}</c->
<c- p>};</c->



<c- k>struct</c-> <c- nl>some_type</c-> <c- p>:</c-> <c- n>add_postfix_increment</c-> <c- p>{</c->
    <c- n>some_type</c-><c- o>&amp;</c-> <c- k>operator</c-><c- o>++</c-><c- p>()</c-> <c- p>{</c-> <c- p>...</c-> <c- p>}</c->
<c- p>};</c->
</pre>
   </table>
   <p>The proposed examples aren’t much shorter, but they are certainly simpler by comparison.</p>
   <h4 class="heading settled" data-level="4.2.1" id="builder-pattern"><span class="secno">4.2.1. </span><span class="content">Builder pattern</span><a class="self-link" href="#builder-pattern"></a></h4>
   <p>Once we start to do any more with CRTP, complexity quickly increases, whereas with this proposal, it stays remarkably low.</p>
   <p>Let’s say we have a builder that does multiple things. We might start with:</p>
<pre class="language-cpp highlight"><c- k>struct</c-> <c- n>Builder</c-> <c- p>{</c->
  <c- n>Builder</c-><c- o>&amp;</c-> <c- n>a</c-><c- p>()</c-> <c- p>{</c-> <c- d>/* ... */</c-><c- p>;</c-> <c- k>return</c-> <c- o>*</c-><c- k>this</c-><c- p>;</c-> <c- p>}</c->
  <c- n>Builder</c-><c- o>&amp;</c-> <c- n>b</c-><c- p>()</c-> <c- p>{</c-> <c- d>/* ... */</c-><c- p>;</c-> <c- k>return</c-> <c- o>*</c-><c- k>this</c-><c- p>;</c-> <c- p>}</c->
  <c- n>Builder</c-><c- o>&amp;</c-> <c- n>c</c-><c- p>()</c-> <c- p>{</c-> <c- d>/* ... */</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>Builder</c-><c- p>().</c-><c- n>a</c-><c- p>().</c-><c- n>b</c-><c- p>().</c-><c- n>a</c-><c- p>().</c-><c- n>b</c-><c- p>().</c-><c- n>c</c-><c- p>();</c->    
</pre>
   <p>But now we want to create a specialized builder with new operations <code class="highlight"><c- n>d</c-><c- p>()</c-></code> and <code class="highlight"><c- n>e</c-><c- p>()</c-></code>. This specialized builder needs new member functions, and we don’t want to burden existing users with them. We also want <code class="highlight"><c- n>Special</c-><c- p>().</c-><c- n>a</c-><c- p>().</c-><c- n>d</c-><c- p>()</c-></code> to work, so we need to use CRTP to <em>conditionally</em> return either a <code class="highlight"><c- n>Builder</c-><c- o>&amp;</c-></code> or a <code class="highlight"><c- n>Special</c-><c- o>&amp;</c-></code>:</p>
   <table style="width:100%">
    <tbody>
     <tr>
      <th style="width:33%">C++17
      <th style="width:33%"><a href="#syntax-1">§3.1.1 Explicit this-annotated parameter</a>
      <th style="width:33%"><a href="#syntax-4">§3.1.4 Trailing type sans identifier</a>
     <tr>
      <td>
<pre class="language-cpp highlight"><c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-> <c- n>D</c-><c- o>=</c-><c- b>void</c-><c- o>></c->
<c- k>class</c-> <c- nc>Builder</c-> <c- p>{</c->
  <c- k>using</c-> <c- n>Derived</c-> <c- o>=</c-> <c- n>conditional_t</c-><c- o>&lt;</c-><c- n>is_void_v</c-><c- o>&lt;</c-><c- n>D</c-><c- o>></c-><c- p>,</c-> <c- n>Builder</c-><c- p>,</c-> <c- n>D</c-><c- o>></c-><c- p>;</c->
  <c- n>Derived</c-><c- o>&amp;</c-> <c- n>self</c-><c- p>()</c-> <c- p>{</c->
    <c- k>return</c-> <c- o>*</c-><c- k>static_cast</c-><c- o>&lt;</c-><c- n>Derived</c-><c- o>*></c-><c- p>(</c-><c- k>this</c-><c- p>);</c->
  <c- p>}</c->
  
<c- k>public</c-><c- o>:</c->
  <c- n>Derived</c-><c- o>&amp;</c-> <c- n>a</c-><c- p>()</c-> <c- p>{</c-> <c- d>/* ... */</c-><c- p>;</c-> <c- k>return</c-> <c- nf>self</c-><c- p>();</c-> <c- p>}</c->
  <c- n>Derived</c-><c- o>&amp;</c-> <c- n>b</c-><c- p>()</c-> <c- p>{</c-> <c- d>/* ... */</c-><c- p>;</c-> <c- k>return</c-> <c- nf>self</c-><c- p>();</c-> <c- p>}</c->
  <c- n>Derived</c-><c- o>&amp;</c-> <c- n>c</c-><c- p>()</c-> <c- p>{</c-> <c- d>/* ... */</c-><c- p>;</c-> <c- k>return</c-> <c- nf>self</c-><c- p>();</c-> <c- p>}</c->
<c- p>};</c->

<c- k>struct</c-> <c- nl>Special</c-> <c- p>:</c-> <c- n>Builder</c-><c- o>&lt;</c-><c- n>Special</c-><c- o>></c-> <c- p>{</c->
  <c- n>Special</c-><c- o>&amp;</c-> <c- n>d</c-><c- p>()</c-> <c- p>{</c-> <c- d>/* ... */</c-><c- p>;</c-> <c- k>return</c-> <c- o>*</c-><c- k>this</c-><c- p>;</c-> <c- p>}</c->
  <c- n>Special</c-><c- o>&amp;</c-> <c- n>e</c-><c- p>()</c-> <c- p>{</c-> <c- d>/* ... */</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>Builder</c-><c- p>().</c-><c- n>a</c-><c- p>().</c-><c- n>b</c-><c- p>().</c-><c- n>a</c-><c- p>().</c-><c- n>b</c-><c- p>().</c-><c- n>c</c-><c- p>();</c->
<c- n>Special</c-><c- p>().</c-><c- n>a</c-><c- p>().</c-><c- n>d</c-><c- p>().</c-><c- n>e</c-><c- p>().</c-><c- n>a</c-><c- p>();</c->
</pre>
      <td>
<pre class="language-cpp highlight"><c- k>struct</c-> <c- n>Builder</c-> <c- p>{</c->
    <c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-> <c- n>Self</c-><c- o>></c->
    <c- n>Self</c-><c- o>&amp;</c-> <c- n>a</c-><c- p>(</c-><c- k>this</c-> <c- n>Self</c-><c- o>&amp;&amp;</c-> <c- n>self</c-><c- p>)</c-> <c- p>{</c-> <c- d>/* ... */</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- n>Self</c-><c- o>></c->
    <c- n>Self</c-><c- o>&amp;</c-> <c- n>b</c-><c- p>(</c-><c- k>this</c-> <c- n>Self</c-><c- o>&amp;&amp;</c-> <c- n>self</c-><c- p>)</c-> <c- p>{</c-> <c- d>/* ... */</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- n>Self</c-><c- o>></c->
    <c- n>Self</c-><c- o>&amp;</c-> <c- n>c</c-><c- p>(</c-><c- k>this</c-> <c- n>Self</c-><c- o>&amp;&amp;</c-> <c- n>self</c-><c- p>)</c-> <c- p>{</c-> <c- d>/* ... */</c-><c- p>;</c-> <c- k>return</c-> <c- n>self</c-><c- p>;</c-> <c- p>}</c->
<c- p>};</c->

<c- k>struct</c-> <c- nl>Special</c-> <c- p>:</c-> <c- n>Builder</c-> <c- p>{</c->
    <c- n>Special</c-><c- o>&amp;</c-> <c- n>d</c-><c- p>()</c-> <c- p>{</c-> <c- d>/* ... */</c-><c- p>;</c-> <c- k>return</c-> <c- o>*</c-><c- k>this</c-><c- p>;</c-> <c- p>}</c->
    <c- n>Special</c-><c- o>&amp;</c-> <c- n>e</c-><c- p>()</c-> <c- p>{</c-> <c- d>/* ... */</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>Builder</c-><c- p>().</c-><c- n>a</c-><c- p>().</c-><c- n>b</c-><c- p>().</c-><c- n>a</c-><c- p>().</c-><c- n>b</c-><c- p>().</c-><c- n>c</c-><c- p>();</c->
<c- n>Special</c-><c- p>().</c-><c- n>a</c-><c- p>().</c-><c- n>d</c-><c- p>().</c-><c- n>e</c-><c- p>().</c-><c- n>a</c-><c- p>();</c->
</pre>
      <td>
<pre class="language-cpp highlight"><c- k>struct</c-> <c- n>Builder</c-> <c- p>{</c->
    <c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-> <c- n>Self</c-><c- o>></c->
    <c- n>Self</c-><c- o>&amp;</c-> <c- n>a</c-><c- p>()</c-> <c- n>Self</c-> <c- p>{</c-> <c- d>/* ... */</c-><c- p>;</c-> <c- k>return</c-> <c- o>*</c-><c- k>this</c-><c- p>;</c-> <c- p>}</c->
    
    <c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-> <c- n>Self</c-><c- o>></c->
    <c- n>Self</c-><c- o>&amp;</c-> <c- n>b</c-><c- p>()</c-> <c- n>Self</c-> <c- p>{</c-> <c- d>/* ... */</c-><c- p>;</c-> <c- k>return</c-> <c- o>*</c-><c- k>this</c-><c- p>;</c-> <c- p>}</c->        
    
    <c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-> <c- n>Self</c-><c- o>></c->
    <c- n>Self</c-><c- o>&amp;</c-> <c- n>c</c-><c- p>()</c-> <c- n>Self</c-> <c- p>{</c-> <c- d>/* ... */</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- k>struct</c-> <c- nl>Special</c-> <c- p>:</c-> <c- n>Builder</c-> <c- p>{</c->
    <c- n>Special</c-><c- o>&amp;</c-> <c- n>d</c-><c- p>()</c-> <c- p>{</c-> <c- d>/* ... */</c-><c- p>;</c-> <c- k>return</c-> <c- o>*</c-><c- k>this</c-><c- p>;</c-> <c- p>}</c->
    <c- n>Special</c-><c- o>&amp;</c-> <c- n>e</c-><c- p>()</c-> <c- p>{</c-> <c- d>/* ... */</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>Builder</c-><c- p>().</c-><c- n>a</c-><c- p>().</c-><c- n>b</c-><c- p>().</c-><c- n>a</c-><c- p>().</c-><c- n>b</c-><c- p>().</c-><c- n>c</c-><c- p>();</c->
<c- n>Special</c-><c- p>().</c-><c- n>a</c-><c- p>().</c-><c- n>d</c-><c- p>().</c-><c- n>e</c-><c- p>().</c-><c- n>a</c-><c- p>();</c->
</pre>
   </table>
   <p>The code on the right is dramatically easier to understand and therefore more accessible to more programmers than the code on the left.</p>
   <p>But wait! There’s more!</p>
   <p>What if we added a <em>super</em>-specialized builder, a more special form of <code class="highlight"><c- n>Special</c-></code>? Now we need <code class="highlight"><c- n>Special</c-></code> to opt-in to CRTP so that it knows which type to pass to <code class="highlight"><c- n>Builder</c-></code>, ensuring that everything in the hierarchy returns the correct type. It’s about this point that most programmers would give up. But with this proposal, there’s no problem!</p>
   <table style="width:100%">
    <tbody>
     <tr>
      <th style="width:33%">C++17
      <th style="width:33%"><a href="#syntax-1">§3.1.1 Explicit this-annotated parameter</a>
      <th style="width:33%"><a href="#syntax-4">§3.1.4 Trailing type sans identifier</a>
     <tr>
      <td>
<pre class="language-cpp highlight"><c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-> <c- n>D</c-><c- o>=</c-><c- b>void</c-><c- o>></c->
<c- k>class</c-> <c- nc>Builder</c-> <c- p>{</c->
<c- k>protected</c-><c- o>:</c->
  <c- k>using</c-> <c- n>Derived</c-> <c- o>=</c-> <c- n>conditional_t</c-><c- o>&lt;</c-><c- n>is_void_v</c-><c- o>&lt;</c-><c- n>D</c-><c- o>></c-><c- p>,</c-> <c- n>Builder</c-><c- p>,</c-> <c- n>D</c-><c- o>></c-><c- p>;</c->
  <c- n>Derived</c-><c- o>&amp;</c-> <c- n>self</c-><c- p>()</c-> <c- p>{</c->
    <c- k>return</c-> <c- o>*</c-><c- k>static_cast</c-><c- o>&lt;</c-><c- n>Derived</c-><c- o>*></c-><c- p>(</c-><c- k>this</c-><c- p>);</c->
  <c- p>}</c->
  
<c- k>public</c-><c- o>:</c->
  <c- n>Derived</c-><c- o>&amp;</c-> <c- n>a</c-><c- p>()</c-> <c- p>{</c-> <c- d>/* ... */</c-><c- p>;</c-> <c- k>return</c-> <c- nf>self</c-><c- p>();</c-> <c- p>}</c->
  <c- n>Derived</c-><c- o>&amp;</c-> <c- n>b</c-><c- p>()</c-> <c- p>{</c-> <c- d>/* ... */</c-><c- p>;</c-> <c- k>return</c-> <c- nf>self</c-><c- p>();</c-> <c- p>}</c->
  <c- n>Derived</c-><c- o>&amp;</c-> <c- n>c</c-><c- p>()</c-> <c- p>{</c-> <c- d>/* ... */</c-><c- p>;</c-> <c- k>return</c-> <c- nf>self</c-><c- p>();</c-> <c- p>}</c->
<c- p>};</c->

<c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-> <c- n>D</c-><c- o>=</c-><c- b>void</c-><c- o>></c->
<c- k>struct</c-> <c- nl>Special</c->
  <c- p>:</c-> <c- n>Builder</c-><c- o>&lt;</c-><c- n>conditional_t</c-><c- o>&lt;</c-><c- n>is_void_v</c-><c- o>&lt;</c-><c- n>D</c-><c- o>></c-><c- p>,</c-><c- n>Special</c-><c- o>&lt;</c-><c- n>D</c-><c- o>></c-><c- p>,</c-><c- n>D</c-><c- o>></c->
<c- p>{</c->
  <c- k>using</c-> <c- n>Derived</c-> <c- o>=</c-> <c- k>typename</c-> <c- n>Special</c-><c- o>::</c-><c- n>Builder</c-><c- o>::</c-><c- n>Derived</c-><c- p>;</c->
  <c- n>Derived</c-><c- o>&amp;</c-> <c- n>d</c-><c- p>()</c-> <c- p>{</c-> <c- d>/* ... */</c-><c- p>;</c-> <c- k>return</c-> <c- k>this</c-><c- o>-></c-><c- n>self</c-><c- p>();</c-> <c- p>}</c->
  <c- n>Derived</c-><c- o>&amp;</c-> <c- n>e</c-><c- p>()</c-> <c- p>{</c-> <c- d>/* ... */</c-><c- p>;</c-> <c- k>return</c-> <c- k>this</c-><c- o>-></c-><c- n>self</c-><c- p>();</c-> <c- p>}</c->
<c- p>};</c->

<c- k>struct</c-> <c- nl>Super</c-> <c- p>:</c-> <c- n>Special</c-><c- o>&lt;</c-><c- n>Super</c-><c- o>></c->
<c- p>{</c->
    <c- n>Super</c-><c- o>&amp;</c-> <c- n>f</c-><c- p>()</c-> <c- p>{</c-> <c- d>/* ... */</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>Builder</c-><c- p>().</c-><c- n>a</c-><c- p>().</c-><c- n>b</c-><c- p>().</c-><c- n>a</c-><c- p>().</c-><c- n>b</c-><c- p>().</c-><c- n>c</c-><c- p>();</c->
<c- n>Special</c-><c- p>().</c-><c- n>a</c-><c- p>().</c-><c- n>d</c-><c- p>().</c-><c- n>e</c-><c- p>().</c-><c- n>a</c-><c- p>();</c->
<c- n>Super</c-><c- p>().</c-><c- n>a</c-><c- p>().</c-><c- n>d</c-><c- p>().</c-><c- n>f</c-><c- p>().</c-><c- n>e</c-><c- p>();</c->
</pre>
      <td>
<pre class="language-cpp highlight"><c- k>struct</c-> <c- n>Builder</c-> <c- p>{</c->
    <c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-> <c- n>Self</c-><c- o>></c->
    <c- n>Self</c-><c- o>&amp;</c-> <c- n>a</c-><c- p>(</c-><c- k>this</c-> <c- n>Self</c-><c- o>&amp;&amp;</c-> <c- n>self</c-><c- p>)</c-> <c- p>{</c-> <c- d>/* ... */</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- n>Self</c-><c- o>></c->
    <c- n>Self</c-><c- o>&amp;</c-> <c- n>b</c-><c- p>(</c-><c- k>this</c-> <c- n>Self</c-><c- o>&amp;&amp;</c-> <c- n>self</c-><c- p>)</c-> <c- p>{</c-> <c- d>/* ... */</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- n>Self</c-><c- o>></c->
    <c- n>Self</c-><c- o>&amp;</c-> <c- n>c</c-><c- p>(</c-><c- k>this</c-> <c- n>Self</c-><c- o>&amp;&amp;</c-> <c- n>self</c-><c- p>)</c-> <c- p>{</c-> <c- d>/* ... */</c-><c- p>;</c-> <c- k>return</c-> <c- n>self</c-><c- p>;</c-> <c- p>}</c->        
<c- p>};</c->

<c- k>struct</c-> <c- nl>Special</c-> <c- p>:</c-> <c- n>Builder</c-> <c- p>{</c->
    <c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-> <c- n>Self</c-><c- o>></c->
    <c- n>Self</c-><c- o>&amp;</c-> <c- n>d</c-><c- p>(</c-><c- k>this</c-> <c- n>Self</c-><c- o>&amp;&amp;</c-> <c- n>self</c-><c- p>)</c-> <c- p>{</c-> <c- d>/* ... */</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- n>Self</c-><c- o>></c->
    <c- n>Self</c-><c- o>&amp;</c-> <c- n>e</c-><c- p>(</c-><c- k>this</c-> <c- n>Self</c-><c- o>&amp;&amp;</c-> <c- n>self</c-><c- p>)</c-> <c- p>{</c-> <c- d>/* ... */</c-><c- p>;</c-> <c- k>return</c-> <c- n>self</c-><c- p>;</c-> <c- p>}</c->
<c- p>};</c->

<c- k>struct</c-> <c- nl>Super</c-> <c- p>:</c-> <c- n>Special</c-> <c- p>{</c->
    <c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-> <c- n>Self</c-><c- o>></c->
    <c- n>Self</c-><c- o>&amp;</c-> <c- n>f</c-><c- p>(</c-><c- k>this</c-> <c- n>Self</c-><c- o>&amp;&amp;</c-> <c- n>self</c-><c- p>)</c-> <c- p>{</c-> <c- d>/* ... */</c-><c- p>;</c-> <c- k>return</c-> <c- n>self</c-><c- p>;</c-> <c- p>}</c->
<c- p>};</c->

<c- n>Builder</c-><c- p>().</c-><c- n>a</c-><c- p>().</c-><c- n>b</c-><c- p>().</c-><c- n>a</c-><c- p>().</c-><c- n>b</c-><c- p>().</c-><c- n>c</c-><c- p>();</c->
<c- n>Special</c-><c- p>().</c-><c- n>a</c-><c- p>().</c-><c- n>d</c-><c- p>().</c-><c- n>e</c-><c- p>().</c-><c- n>a</c-><c- p>();</c->
<c- n>Super</c-><c- p>().</c-><c- n>a</c-><c- p>().</c-><c- n>d</c-><c- p>().</c-><c- n>f</c-><c- p>().</c-><c- n>e</c-><c- p>();</c->
</pre>
      <td>
<pre class="language-cpp highlight"><c- k>struct</c-> <c- n>Builder</c-> <c- p>{</c->
    <c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-> <c- n>Self</c-><c- o>></c->
    <c- n>Self</c-><c- o>&amp;</c-> <c- n>a</c-><c- p>()</c-> <c- n>Self</c-> <c- p>{</c-> <c- d>/* ... */</c-><c- p>;</c-> <c- k>return</c-> <c- o>*</c-><c- k>this</c-><c- p>;</c-> <c- p>}</c->
    
    <c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-> <c- n>Self</c-><c- o>></c->
    <c- n>Self</c-><c- o>&amp;</c-> <c- n>b</c-><c- p>()</c-> <c- n>Self</c-> <c- p>{</c-> <c- d>/* ... */</c-><c- p>;</c-> <c- k>return</c-> <c- o>*</c-><c- k>this</c-><c- p>;</c-> <c- p>}</c->        
    
    <c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-> <c- n>Self</c-><c- o>></c->
    <c- n>Self</c-><c- o>&amp;</c-> <c- n>c</c-><c- p>()</c-> <c- n>Self</c-> <c- p>{</c-> <c- d>/* ... */</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- k>struct</c-> <c- nl>Special</c-> <c- p>:</c-> <c- n>Builder</c-> <c- p>{</c->
    <c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-> <c- n>Self</c-><c- o>></c->
    <c- n>Self</c-><c- o>&amp;</c-> <c- n>d</c-><c- p>()</c-> <c- n>Self</c-> <c- p>{</c-> <c- d>/* ... */</c-><c- p>;</c-> <c- k>return</c-> <c- o>*</c-><c- k>this</c-><c- p>;</c-> <c- p>}</c->
    
    <c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-> <c- n>Self</c-><c- o>></c->
    <c- n>Self</c-><c- o>&amp;</c-> <c- n>e</c-><c- p>()</c-> <c- n>Self</c-> <c- p>{</c-> <c- d>/* ... */</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- k>struct</c-> <c- nl>Super</c-> <c- p>:</c-> <c- n>Special</c-> <c- p>{</c->
    <c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-> <c- n>Self</c-><c- o>></c->
    <c- n>Self</c-><c- o>&amp;</c-> <c- n>f</c-><c- p>()</c-> <c- n>Self</c-> <c- p>{</c-> <c- d>/* ... */</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>Builder</c-><c- p>().</c-><c- n>a</c-><c- p>().</c-><c- n>b</c-><c- p>().</c-><c- n>a</c-><c- p>().</c-><c- n>b</c-><c- p>().</c-><c- n>c</c-><c- p>();</c->
<c- n>Special</c-><c- p>().</c-><c- n>a</c-><c- p>().</c-><c- n>d</c-><c- p>().</c-><c- n>e</c-><c- p>().</c-><c- n>a</c-><c- p>();</c->
<c- n>Super</c-><c- p>().</c-><c- n>a</c-><c- p>().</c-><c- n>d</c-><c- p>().</c-><c- n>f</c-><c- p>().</c-><c- n>e</c-><c- p>();</c->
</pre>
   </table>
   <p>The code on the right is much easier in all contexts. There are so many situations where this idiom, if available, would give programmers a better solution for problems that they cannot easily solve today.</p>
   <p>Note that the <code class="highlight"><c- n>Super</c-></code> implementations with this proposal opt-in to further derivation, since it’s a no-brainer at this point.</p>
   <h3 class="heading settled" data-level="4.3" id="recursive-lambdas"><span class="secno">4.3. </span><span class="content">Recursive Lambdas</span><a class="self-link" href="#recursive-lambdas"></a></h3>
   <p>The explicit object parameter syntax offers an alternative solution to implementing a recursive lambda as compared to <a data-link-type="biblio" href="#biblio-p0839r0">[P0839R0]</a>, since now we’ve opened up the possibility of allowing a lambda to reference itself. To do this, we need a way to <em>name</em> the lambda. The trailing object type syntax does not allow for an identifier, and therefore <em>does not</em> help us solve this problem.</p>
<pre class="language-cpp highlight"><c- c1>// as proposed in P0839</c->
<c- k>auto</c-> <c- n>fib</c-> <c- o>=</c-> <c- p>[]</c-> <c- n>self</c-> <c- p>(</c-><c- b>int</c-> <c- n>n</c-><c- p>)</c-> <c- p>{</c->
    <c- k>if</c-> <c- p>(</c-><c- n>n</c-> <c- o>&lt;</c-> <c- mi>2</c-><c- p>)</c-> <c- k>return</c-> <c- n>n</c-><c- p>;</c->
    <c- k>return</c-> <c- nf>self</c-><c- p>(</c-><c- n>n</c-><c- o>-</c-><c- mi>1</c-><c- p>)</c-> <c- o>+</c-> <c- n>self</c-><c- p>(</c-><c- n>n</c-><c- o>-</c-><c- mi>2</c-><c- p>);</c->
<c- p>};</c->

<c- c1>// this proposal</c->
<c- k>auto</c-> <c- n>fib</c-> <c- o>=</c-> <c- p>[](</c-><c- k>this</c-> <c- k>auto</c-> <c- k>const</c-><c- o>&amp;</c-> <c- n>self</c-><c- p>,</c-> <c- b>int</c-> <c- n>n</c-><c- p>)</c-> <c- p>{</c->
    <c- k>if</c-> <c- p>(</c-><c- n>n</c-> <c- o>&lt;</c-> <c- mi>2</c-><c- p>)</c-> <c- k>return</c-> <c- n>n</c-><c- p>;</c->
    <c- k>return</c-> <c- nf>self</c-><c- p>(</c-><c- n>n</c-><c- o>-</c-><c- mi>1</c-><c- p>)</c-> <c- o>+</c-> <c- n>self</c-><c- p>(</c-><c- n>n</c-><c- o>-</c-><c- mi>2</c-><c- p>);</c->
<c- p>};</c->
</pre>
   <p>This works by following the established rules. The call operator of the closure object can also have an explicit object parameter, so in this example, <code class="highlight"><c- n>self</c-></code> is the closure object.</p>
   <p>Combine this with the new style of mixins allowing us to automatically deduce the most derived object, and you get the following example — a simple recursive lambda that counts the number of leaves in a tree.</p>
<pre class="language-c++ highlight"><c- k>struct</c-> <c- n>Node</c-><c- p>;</c->
<c- n>using</c-> <c- n>Tree</c-> <c- o>=</c-> <c- n>variant</c-><c- o>&lt;</c-><c- n>Leaf</c-><c- p>,</c-> <c- n>Node</c-><c- o>*></c-><c- p>;</c->
<c- k>struct</c-> <c- n>Node</c-> <c- p>{</c->
    <c- n>Tree</c-> <c- n>left</c-><c- p>;</c->
    <c- n>Tree</c-> <c- n>right</c-><c- p>;</c->
<c- p>};</c->

<c- b>int</c-> <c- nf>num_leaves</c-><c- p>(</c-><c- n>Tree</c-> <c- k>const</c-><c- o>&amp;</c-> <c- n>tree</c-><c- p>)</c-> <c- p>{</c->
    <c- k>return</c-> <c- n>visit</c-><c- p>(</c-><c- n>overload</c-><c- p>(</c->        <c- c1>// &lt;-----------------------------------+</c->
        <c- p>[](</c-><c- n>Leaf</c-> <c- k>const</c-><c- o>&amp;</c-><c- p>)</c-> <c- p>{</c-> <c- k>return</c-> <c- mi>1</c-><c- p>;</c-> <c- p>},</c->                           <c- c1>//      |</c->
        <c- p>[](</c-><c- n>this</c-> <c- k>auto</c-> <c- k>const</c-><c- o>&amp;</c-> <c- n>self</c-><c- p>,</c-> <c- n>Node</c-><c- o>*</c-> <c- n>n</c-><c- p>)</c-> <c- o>-></c-> <c- b>int</c-> <c- p>{</c->              <c- c1>//      |</c->
            <c- k>return</c-> <c- n>visit</c-><c- p>(</c-><c- n>self</c-><c- p>,</c-> <c- n>n</c-><c- o>-></c-><c- n>left</c-><c- p>)</c-> <c- o>+</c-> <c- n>visit</c-><c- p>(</c-><c- n>self</c-><c- p>,</c-> <c- n>n</c-><c- o>-></c-><c- n>right</c-><c- p>);</c-> <c- c1>// &lt;----+    </c->
        <c- p>}</c->
    <c- p>),</c-> <c- n>tree</c-><c- p>);</c->
<c- p>}</c->
</pre>
   In the calls to <code class="highlight"><c- n>visit</c-></code>, <code class="highlight"><c- n>self</c-></code> isn’t the lambda; <code class="highlight"><c- n>self</c-></code> is the <code class="highlight"><c- n>overload</c-></code> wrapper. This works straight out of the box. 
   <h3 class="heading settled" data-level="4.4" id="by-value-member-functions"><span class="secno">4.4. </span><span class="content">By-value member functions</span><a class="self-link" href="#by-value-member-functions"></a></h3>
   <p>This section presents some of the cases for by-value member functions.</p>
   <h4 class="heading settled" data-level="4.4.1" id="move-into-parameter"><span class="secno">4.4.1. </span><span class="content">For move-into-parameter chaining</span><a class="self-link" href="#move-into-parameter"></a></h4>
   <p>Say you wanted to provide a <code class="highlight"><c- p>.</c-><c- n>sorted</c-><c- p>()</c-></code> method on a data structure. Such a method naturally wants to operate on a copy. Taking the parameter by value will cleanly and correctly move into the parameter if the original object is an rvalue without requiring templates.</p>
<pre class="language-cpp highlight"><c- k>struct</c-> <c- nl>my_vector</c-> <c- p>:</c-> <c- n>vector</c-><c- o>&lt;</c-><c- b>int</c-><c- o>></c-> <c- p>{</c->
  <c- k>auto</c-> <c- n>sorted</c-><c- p>(</c-><c- k>this</c-> <c- n>my_vector</c-> <c- n>self</c-><c- p>)</c-> <c- o>-></c-> <c- n>my_vector</c-> <c- p>{</c->
    <c- n>sort</c-><c- p>(</c-><c- n>self</c-><c- p>.</c-><c- n>begin</c-><c- p>(),</c-> <c- n>self</c-><c- p>.</c-><c- n>end</c-><c- p>());</c->
    <c- k>return</c-> <c- n>self</c-><c- p>;</c->
  <c- p>}</c->
<c- p>};</c->
</pre>
   <h4 class="heading settled" data-level="4.4.2" id="by-value-member-functions-for-performance"><span class="secno">4.4.2. </span><span class="content">For performance</span><a class="self-link" href="#by-value-member-functions-for-performance"></a></h4>
   <p>It’s been established that if you want the best performance, you should pass small types by value to avoid an indirection penalty. One such small type is <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>string_view</c-></code>. <a href="https://abseil.io/tips/1">Abseil Tip #1</a> for instance, states:</p>
   <blockquote>
    <p>Unlike other string types, you should pass <code class="highlight"><c- n>string_view</c-></code> by value just like you would an <code class="highlight"><c- b>int</c-></code> or a <code class="highlight"><c- b>double</c-></code> because <code class="highlight"><c- n>string_view</c-></code> is a small value.</p>
   </blockquote>
   <p>There is, however, one place today where you simply <em>cannot</em> pass types like <code class="highlight"><c- n>string_view</c-></code> by value: to their own member functions. The implicit object parameter is always a reference, so any such member functions that do not get inlined incur a double indirection.</p>
   <p>As an easy performance optimization, any member function of small types that does not perform any modifications can take the object parameter by value. This is possible <em>only</em> when using the explicit object parameter syntax; there is no way to express this idea with a trailing type. Here is an example of some member functions of <code class="highlight"><c- n>basic_string_view</c-></code> assuming that we are just using <code class="highlight"><c- n>charT</c-> <c- k>const</c-><c- o>*</c-></code> as <code class="highlight"><c- n>iterator</c-></code>:</p>
<pre class="highlight"><c- k>template</c-> <c- o>&lt;</c-><c- k>class</c-> <c- nc>charT</c-><c- p>,</c-> <c- k>class</c-> <c- nc>traits</c-> <c- o>=</c-> <c- n>char_traits</c-><c- o>&lt;</c-><c- n>charT</c-><c- o>>></c->
<c- k>class</c-> <c- nc>basic_string_view</c-> <c- p>{</c->
<c- k>private</c-><c- o>:</c->
    <c- n>const_pointer</c-> <c- n>data_</c-><c- p>;</c->
    <c- n>size_type</c-> <c- n>size_</c-><c- p>;</c->
<c- k>public</c-><c- o>:</c->
    <c- k>constexpr</c-> <c- n>const_iterator</c-> <c- n>begin</c-><c- p>(</c-><c- k>this</c-> <c- n>basic_string_view</c-> <c- n>self</c-><c- p>)</c-> <c- p>{</c->
        <c- k>return</c-> <c- n>self</c-><c- p>.</c-><c- n>data_</c-><c- p>;</c->
    <c- p>}</c->
    
    <c- k>constexpr</c-> <c- n>const_iterator</c-> <c- n>end</c-><c- p>(</c-><c- k>this</c-> <c- n>basic_string_view</c-> <c- n>self</c-><c- p>)</c-> <c- p>{</c->
        <c- k>return</c-> <c- n>self</c-><c- p>.</c-><c- n>data_</c-> <c- o>+</c-> <c- n>self</c-><c- p>.</c-><c- n>size_</c-><c- p>;</c->
    <c- p>}</c->
    
    <c- k>constexpr</c-> <c- b>size_t</c-> <c- n>size</c-><c- p>(</c-><c- k>this</c-> <c- n>basic_string_view</c-> <c- n>self</c-><c- p>)</c-> <c- p>{</c->
        <c- k>return</c-> <c- n>self</c-><c- p>.</c-><c- n>size_</c-><c- p>;</c->
    <c- p>}</c->
    
    <c- k>constexpr</c-> <c- n>const_reference</c-> <c- k>operator</c-><c- p>[](</c-><c- k>this</c-> <c- n>basic_string_view</c-> <c- n>self</c-><c- p>,</c-> <c- n>size_type</c-> <c- n>pos</c-><c- p>)</c-> <c- p>{</c->
        <c- k>return</c-> <c- n>self</c-><c- p>.</c-><c- n>data_</c-><c- p>[</c-><c- n>pos</c-><c- p>];</c->
    <c- p>}</c->
<c- p>};</c->
</pre>
   <p>Most of the member functions can be rewritten this way for a free performance boost.</p>
   <p>The same can be said for types that aren’t only cheap to copy, but have no state at all. Compare these two implementations of <code class="highlight"><c- n>less_than</c-></code>:</p>
   <table style="width:100%">
    <tbody>
     <tr>
      <th style="width:50%">C++17
      <th style="width:50%"><a href="#syntax-1">§3.1.1 Explicit this-annotated parameter</a>
     <tr>
      <td>
<pre class="language-c++ highlight"><c- k>struct</c-> <c- n>less_than</c-> <c- p>{</c->
  <c- n>template</c-> <c- o>&lt;</c-><c- kr>typename</c-> <c- n>T</c-><c- p>,</c-> <c- kr>typename</c-> <c- n>U</c-><c- o>></c->
  <c- b>bool</c-> <c- n>operator</c-><c- p>()(</c-><c- n>T</c-> <c- k>const</c-><c- o>&amp;</c-> <c- n>lhs</c-><c- p>,</c-> <c- n>U</c-> <c- k>const</c-><c- o>&amp;</c-> <c- n>rhs</c-><c- p>)</c-> <c- p>{</c->
    <c- k>return</c-> <c- n>lhs</c-> <c- o>&lt;</c-> <c- n>rhs</c-><c- p>;</c->
  <c- p>}</c->
<c- p>};</c->
</pre>
      <td>
<pre class="language-c++ highlight"><c- k>struct</c-> <c- n>less_than</c-> <c- p>{</c->
  <c- n>template</c-> <c- o>&lt;</c-><c- kr>typename</c-> <c- n>T</c-><c- p>,</c-> <c- kr>typename</c-> <c- n>U</c-><c- o>></c->
  <c- b>bool</c-> <c- n>operator</c-><c- p>()(</c-><c- n>this</c-> <c- n>less_than</c-><c- p>,</c->
          <c- n>T</c-> <c- k>const</c-><c- o>&amp;</c-> <c- n>lhs</c-><c- p>,</c-> <c- n>U</c-> <c- k>const</c-><c- o>&amp;</c-> <c- n>rhs</c-><c- p>)</c-> <c- p>{</c->
    <c- k>return</c-> <c- n>lhs</c-> <c- o>&lt;</c-> <c- n>rhs</c-><c- p>;</c->
  <c- p>}</c->
<c- p>};</c->
</pre>
   </table>
   <p>In C++17, invoking <code class="highlight"><c- n>less_than</c-><c- p>()(</c-><c- n>x</c-><c- p>,</c-> <c- n>y</c-><c- p>)</c-></code> still requires an implicit reference to the <code class="highlight"><c- n>less_than</c-></code> object — completely unnecessary work when copying it is free. The compiler knows it doesn’t have to do anything. We <em>want</em> to pass <code class="highlight"><c- n>less_than</c-></code> by value here. Indeed, this specific situation is the main motivation for <a data-link-type="biblio" href="#biblio-p1169r0">[P1169R0]</a>.</p>
   <h3 class="heading settled" data-level="4.5" id="sfinae-friendly-callables"><span class="secno">4.5. </span><span class="content">SFINAE-friendly callables</span><a class="self-link" href="#sfinae-friendly-callables"></a></h3>
   <p>A seemingly unrelated problem to the question of code quadruplication is that of writing numerous overloads for function wrappers, as demonstrated in <a data-link-type="biblio" href="#biblio-p0826r0">[P0826R0]</a>. Consider what happens if we implement <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>not_fn</c-><c- p>()</c-></code> as currently specified:</p>
<pre class="language-cpp highlight"><c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-> <c- n>F</c-><c- o>></c->
<c- k>class</c-> <c- nc>call_wrapper</c-> <c- p>{</c->
    <c- n>F</c-> <c- n>f</c-><c- p>;</c->
<c- k>public</c-><c- o>:</c->
    <c- c1>// ...</c->
    <c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-><c- p>...</c-> <c- n>Args</c-><c- o>></c->
    <c- k>auto</c-> <c- k>operator</c-><c- p>()(</c-><c- n>Args</c-><c- o>&amp;&amp;</c-><c- p>...</c-> <c- p>)</c-> <c- o>&amp;</c->
        <c- o>-></c-> <c- k>decltype</c-><c- p>(</c-><c- o>!</c-><c- n>declval</c-><c- o>&lt;</c-><c- n>invoke_result_t</c-><c- o>&lt;</c-><c- n>F</c-><c- o>&amp;</c-><c- p>,</c-> <c- n>Args</c-><c- p>...</c-><c- o>>></c-><c- p>());</c->

    <c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-><c- p>...</c-> <c- n>Args</c-><c- o>></c->
    <c- k>auto</c-> <c- k>operator</c-><c- p>()(</c-><c- n>Args</c-><c- o>&amp;&amp;</c-><c- p>...</c-> <c- p>)</c-> <c- k>const</c-><c- o>&amp;</c->
        <c- o>-></c-> <c- k>decltype</c-><c- p>(</c-><c- o>!</c-><c- n>declval</c-><c- o>&lt;</c-><c- n>invoke_result_t</c-><c- o>&lt;</c-><c- n>F</c-> <c- k>const</c-><c- o>&amp;</c-><c- p>,</c-> <c- n>Args</c-><c- p>...</c-><c- o>>></c-><c- p>());</c->

    <c- c1>// ... same for &amp;&amp; and const &amp;&amp; ...</c->
<c- p>};</c->

<c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-> <c- n>F</c-><c- o>></c->
<c- k>auto</c-> <c- n>not_fn</c-><c- p>(</c-><c- n>F</c-><c- o>&amp;&amp;</c-> <c- n>f</c-><c- p>)</c-> <c- p>{</c->
    <c- k>return</c-> <c- n>call_wrapper</c-><c- o>&lt;</c-><c- n>decay_t</c-><c- o>&lt;</c-><c- n>F</c-><c- o>>></c-><c- p>{</c-><c- n>forward</c-><c- o>&lt;</c-><c- n>F</c-><c- o>></c-><c- p>(</c-><c- n>f</c-><c- p>)};</c->
<c- p>}</c->
</pre>
   <p>As described in the paper, this implementation has two pathological cases: one in which the callable is SFINAE-unfriendly, causing the call to be ill-formed where it would otherwise work; and one in which overload is deleted, causing the call to fall back to a different overload when it should fail instead:</p>
<pre class="language-cpp highlight"><c- k>struct</c-> <c- n>unfriendly</c-> <c- p>{</c->
    <c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-> <c- n>T</c-><c- o>></c->
    <c- k>auto</c-> <c- k>operator</c-><c- p>()(</c-><c- n>T</c-> <c- n>v</c-><c- p>)</c-> <c- p>{</c->
        <c- k>static_assert</c-><c- p>(</c-><c- n>is_same_v</c-><c- o>&lt;</c-><c- n>T</c-><c- p>,</c-> <c- b>int</c-><c- o>></c-><c- p>);</c->
        <c- k>return</c-> <c- n>v</c-><c- p>;</c->
    <c- p>}</c->

    <c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-> <c- n>T</c-><c- o>></c->
    <c- k>auto</c-> <c- k>operator</c-><c- p>()(</c-><c- n>T</c-> <c- n>v</c-><c- p>)</c-> <c- k>const</c-> <c- p>{</c->
        <c- k>static_assert</c-><c- p>(</c-><c- n>is_same_v</c-><c- o>&lt;</c-><c- n>T</c-><c- p>,</c-> <c- b>double</c-><c- o>></c-><c- p>);</c->
        <c- k>return</c-> <c- n>v</c-><c- p>;</c->
    <c- p>}</c->
<c- p>};</c->

<c- k>struct</c-> <c- n>fun</c-> <c- p>{</c->
    <c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-><c- p>...</c-> <c- n>Args</c-><c- o>></c->
    <c- b>void</c-> <c- k>operator</c-><c- p>()(</c-><c- n>Args</c-><c- o>&amp;&amp;</c-><c- p>...)</c-> <c- o>=</c-> <c- k>delete</c-><c- p>;</c->

    <c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-><c- p>...</c-> <c- n>Args</c-><c- o>></c->
    <c- b>bool</c-> <c- k>operator</c-><c- p>()(</c-><c- n>Args</c-><c- o>&amp;&amp;</c-><c- p>...)</c-> <c- k>const</c-> <c- p>{</c-> <c- k>return</c-> true<c- p>;</c-> <c- p>}</c->
<c- p>};</c->

<c- n>std</c-><c- o>::</c-><c- n>not_fn</c-><c- p>(</c-><c- n>unfriendly</c-><c- p>{})(</c-><c- mi>1</c-><c- p>);</c-> <c- c1>// static assert!</c->
                              <c- c1>// even though the non-const overload is viable and would be the</c->
                              <c- c1>// best match, during overload resolution, both overloads of</c->
                              <c- c1>// unfriendly have to be instantiated - and the second one is a</c->
                              <c- c1>// hard compile error.</c->

<c- n>std</c-><c- o>::</c-><c- n>not_fn</c-><c- p>(</c-><c- n>fun</c-><c- p>{})();</c->         <c- c1>// ok!? Returns false</c->
                              <c- c1>// even though we want the non-const overload to be deleted, the</c->
                              <c- c1>// const overload of the call_wrapper ends up being viable - and</c->
                              <c- c1>// the only viable candidate.</c->
</pre>
   <p>Gracefully handling SFINAE-unfriendly callables is <strong>not solvable</strong> in C++ today. Preventing fallback can be solved by the addition of another four overloads, so that each of the four <em>cv</em>/ref-qualifiers leads to a pair of overloads: one enabled and one <code class="highlight"><c- n>deleted</c-></code>.</p>
   <p>This proposal solves both problems by allowing <code class="highlight"><c- k>this</c-></code> to be deduced. The following is a complete implementation of <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>not_fn</c-></code>. For simplicity, it makes use of <code class="highlight"><c- n>BOOST_HOF_RETURNS</c-></code> from <a href="https://www.boost.org/doc/libs/1_68_0/libs/hof/doc/html/include/boost/hof/returns.html">Boost.HOF</a> to avoid duplicating expressions:</p>
   <table style="width:100%">
    <tbody>
     <tr>
      <th style="width:50%"><a href="#syntax-1">§3.1.1 Explicit this-annotated parameter</a>
      <th style="width:50%"><a href="#syntax-4">§3.1.4 Trailing type sans identifier</a>
     <tr>
      <td>
<pre class="language-cpp highlight"><c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-> <c- n>F</c-><c- o>></c->
<c- k>struct</c-> <c- n>call_wrapper</c-> <c- p>{</c->
  <c- n>F</c-> <c- n>f</c-><c- p>;</c->

  <c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-> <c- n>Self</c-><c- p>,</c-> <c- k>typename</c-><c- p>...</c-> <c- n>Args</c-><c- o>></c->
  <c- k>auto</c-> <c- k>operator</c-><c- p>()(</c-><c- k>this</c-> <c- n>Self</c-><c- o>&amp;&amp;</c-><c- p>,</c-> <c- n>Args</c-><c- o>&amp;&amp;</c-><c- p>...</c-> <c- n>args</c-><c- p>)</c->
    <c- n>BOOST_HOF_RETURNS</c-><c- p>(</c->
      <c- o>!</c-><c- n>invoke</c-><c- p>(</c->
        <c- n>forward_like</c-><c- o>&lt;</c-><c- n>Self</c-><c- o>></c-><c- p>(</c-><c- k>this</c-><c- o>-></c-><c- n>f</c-><c- p>),</c->
        <c- n>forward</c-><c- o>&lt;</c-><c- n>Args</c-><c- o>></c-><c- p>(</c-><c- n>args</c-><c- p>)...))</c->
<c- p>};</c->

<c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-> <c- n>F</c-><c- o>></c->
<c- k>auto</c-> <c- n>not_fn</c-><c- p>(</c-><c- n>F</c-><c- o>&amp;&amp;</c-> <c- n>f</c-><c- p>)</c-> <c- p>{</c->
  <c- k>return</c-> <c- n>call_wrapper</c-><c- o>&lt;</c-><c- n>decay_t</c-><c- o>&lt;</c-><c- n>F</c-><c- o>>></c-><c- p>{</c-><c- n>forward</c-><c- o>&lt;</c-><c- n>F</c-><c- o>></c-><c- p>(</c-><c- n>f</c-><c- p>)};</c->
<c- p>}</c->
</pre>
      <td>
<pre class="language-cpp highlight"><c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-> <c- n>F</c-><c- o>></c->
<c- k>struct</c-> <c- n>call_wrapper</c-> <c- p>{</c->
  <c- n>F</c-> <c- n>f</c-><c- p>;</c->

  <c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-> <c- n>Self</c-><c- p>,</c-> <c- k>typename</c-><c- p>...</c-> <c- n>Args</c-><c- o>></c->
  <c- k>auto</c-> <c- k>operator</c-><c- p>()(</c-><c- n>Args</c-><c- o>&amp;&amp;</c-><c- p>...</c-> <c- n>args</c-><c- p>)</c-> <c- n>Self</c-><c- o>&amp;&amp;</c->
    <c- n>BOOST_HOF_RETURNS</c-><c- p>(</c->
      <c- o>!</c-><c- n>invoke</c-><c- p>(</c->
        <c- n>forward_like</c-><c- o>&lt;</c-><c- n>Self</c-><c- o>></c-><c- p>(</c-><c- k>this</c-><c- o>-></c-><c- n>call_wrapper</c-><c- o>::</c-><c- n>f</c-><c- p>),</c->
        <c- n>forward</c-><c- o>&lt;</c-><c- n>Args</c-><c- o>></c-><c- p>(</c-><c- n>args</c-><c- p>)...))</c->
<c- p>};</c->

<c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-> <c- n>F</c-><c- o>></c->
<c- k>auto</c-> <c- n>not_fn</c-><c- p>(</c-><c- n>F</c-><c- o>&amp;&amp;</c-> <c- n>f</c-><c- p>)</c-> <c- p>{</c->
  <c- k>return</c-> <c- n>call_wrapper</c-><c- o>&lt;</c-><c- n>decay_t</c-><c- o>&lt;</c-><c- n>F</c-><c- o>>></c-><c- p>{</c-><c- n>forward</c-><c- o>&lt;</c-><c- n>F</c-><c- o>></c-><c- p>(</c-><c- n>f</c-><c- p>)};</c->
<c- p>}</c->
</pre>
   </table>
   <p>With either syntax:</p>
<pre class="language-c++ highlight"><c- n>not_fn</c-><c- p>(</c-><c- n>unfriendly</c-><c- p>{})(</c-><c- mi>1</c-><c- p>);</c-> <c- c1>// ok</c->
<c- n>not_fn</c-><c- p>(</c-><c- n>fun</c-><c- p>{})();</c->         <c- c1>// error</c->
</pre>
   <p>Here, there is only one overload with everything deduced together. The first example now works correctly. <code class="highlight"><c- n>Self</c-></code> gets deduced as <code class="highlight"><c- n>call_wrapper</c-><c- o>&lt;</c-><c- n>unfriendly</c-><c- o>></c-></code>, and the one <code class="highlight"><c- k>operator</c-><c- p>()</c-></code> will only consider <code class="highlight"><c- n>unfriendly</c-></code>'s non-<code class="highlight"><c- k>const</c-></code> call operator. The <code class="highlight"><c- k>const</c-></code> one is never even considered, so it does not have an opportunity to cause problems.</p>
   <p>The second example now also fails correctly. Previously, we had four candidates. The two non-<code class="highlight"><c- k>const</c-></code> options were removed from the overload set due to <code class="highlight"><c- n>fun</c-></code>'s non-<code class="highlight"><c- k>const</c-></code> call operator being <code class="highlight"><c- k>delete</c-></code>d, and the two <code class="highlight"><c- k>const</c-></code> ones which were viable. But now, we only have one candidate. <code class="highlight"><c- n>Self</c-></code> is deduced as <code class="highlight"><c- n>call_wrapper</c-><c- o>&lt;</c-><c- n>fun</c-><c- o>></c-></code>, which requires <code class="highlight"><c- n>fun</c-></code>'s non-<code class="highlight"><c- k>const</c-></code> call operator to be well-formed. Since it is not, the call results in an error. There is no opportunity for fallback since only one overload is ever considered.</p>
   <p>This singular overload has precisely the desired behavior: working for <code class="highlight"><c- n>unfriendly</c-></code>, and not working for <code class="highlight"><c- n>fun</c-></code>.</p>
   <p>This could also be implemented as a lambda completely within the body of <code class="highlight"><c- n>not_fn</c-></code>:</p>
<pre class="language-cpp highlight"><c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-> <c- n>F</c-><c- o>></c->
<c- k>auto</c-> <c- n>not_fn</c-><c- p>(</c-><c- n>F</c-><c- o>&amp;&amp;</c-> <c- n>f</c-><c- p>)</c-> <c- p>{</c->
    <c- k>return</c-> <c- p>[</c-><c- n>f</c-><c- o>=</c-><c- n>forward</c-><c- o>&lt;</c-><c- n>F</c-><c- o>></c-><c- p>(</c-><c- n>f</c-><c- p>)](</c-><c- k>this</c-> <c- k>auto</c-><c- o>&amp;&amp;</c-> <c- n>self</c-><c- p>,</c-> <c- k>auto</c-><c- o>&amp;&amp;</c-><c- p>..</c-> <c- n>args</c-><c- p>)</c->
        <c- n>BOOST_HOF_RETURNS</c-><c- p>(</c->
            <c- o>!</c-><c- n>invoke</c-><c- p>(</c->
                <c- n>forward_like</c-><c- o>&lt;</c-><c- k>decltype</c-><c- p>(</c-><c- n>self</c-><c- p>)</c-><c- o>></c-><c- p>(</c-><c- n>f</c-><c- p>),</c->
                <c- n>forward</c-><c- o>&lt;</c-><c- k>decltype</c-><c- p>(</c-><c- n>args</c-><c- p>)</c-><c- o>></c-><c- p>(</c-><c- n>args</c-><c- p>)...))</c->
        <c- p>;</c->
<c- p>}</c->
</pre>
   <h2 class="heading settled" data-level="5" id="suggested-polls"><span class="secno">5. </span><span class="content">Suggested Polls</span><a class="self-link" href="#suggested-polls"></a></h2>
   <p>We would like to suggest the following polls on this proposal:</p>
   <ol>
    <li data-md>
     <p>Do we want a solution in the direction of this paper — that is, do we want a syntax that allows for deducing the qualifiers and value category of the object parameter for non-static member functions?</p>
    <li data-md>
     <p>[Four-way] We want that solution to be</p>
     <ul>
      <li data-md>
       <p><a href="#syntax-1">§3.1.1 Explicit this-annotated parameter</a></p>
      <li data-md>
       <p><a href="#syntax-2">§3.1.2 Explicit this parameter</a></p>
      <li data-md>
       <p><a href="#syntax-3">§3.1.3 Trailing type with identifier</a></p>
      <li data-md>
       <p><a href="#syntax-4">§3.1.4 Trailing type sans identifier</a></p>
     </ul>
    <li data-md>
     <p>[three-way] Only if <a href="#syntax-1">§3.1.1 Explicit this-annotated parameter</a> or <a href="#syntax-3">§3.1.3 Trailing type with identifier</a> is chosen:</p>
     <ul>
      <li data-md>
       <p><code class="highlight"><c- k>this</c-></code> should be inaccessible and every access must be qualified</p>
      <li data-md>
       <p><code class="highlight"><c- k>this</c-></code> is accessible but every access must be qualified</p>
      <li data-md>
       <p><code class="highlight"><c- k>this</c-></code> is accessible and implicit lookup is permitted.</p>
     </ul>
    <li data-md>
     <p>Should we pursue a solution along the lines presented <a href="#potential-extensions">§3.4 Potential Extension</a> <code class="highlight"><c- k>typename</c-> <c- nl>T</c-><c- p>:</c-> <c- n>B</c-></code>?</p>
   </ol>
   <h2 class="heading settled" data-level="6" id="acknowledgements"><span class="secno">6. </span><span class="content">Acknowledgements</span><a class="self-link" href="#acknowledgements"></a></h2>
   <p>The authors would like to thank:</p>
   <ul>
    <li data-md>
     <p>Jonathan Wakely, for bringing us all together by pointing out we were writing the same paper, twice</p>
    <li data-md>
     <p>Chandler Carruth for a lot of feedback and guidance around many design issues, but especially for help with use cases and the pointer-types for by-value passing</p>
    <li data-md>
     <p>Graham Heynes, Andrew Bennieston, Jeff Snyder for early feedback regarding the meaning of <code class="highlight"><c- k>this</c-></code> inside function bodies</p>
    <li data-md>
     <p>Amy Worthington, Jackie Chen, Vittorio Romeo, Tristan Brindle, Agustín Bergé, Louis Dionne, and Michael Park for early feedback</p>
    <li data-md>
     <p>Guilherme Hartmann for his guidance with the implementation</p>
    <li data-md>
     <p>Richard Smith, Jens Maurer, and Hubert Tong for help with wording</p>
    <li data-md>
     <p>Ville Voutilainen, Herb Sutter, Titus Winters and Bjarne Stroustrup for their guidance in design-space exploration</p>
    <li data-md>
     <p>Eva Conti for furious copy editing, patience, and moral support</p>
   </ul>
  </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-effective">[Effective]
   <dd>Scott Meyers. <a href="https://www.aristeia.com/books.html">Effective C++, Third Edition</a>. 2005. URL: <a href="https://www.aristeia.com/books.html">https://www.aristeia.com/books.html</a>
   <dt id="biblio-p0798r0">[P0798R0]
   <dd>Simon Brand. <a href="https://wg21.link/p0798r0">Monadic operations for std::optional</a>. 6 October 2017. URL: <a href="https://wg21.link/p0798r0">https://wg21.link/p0798r0</a>
   <dt id="biblio-p0826r0">[P0826R0]
   <dd>Agustín Bergé. <a href="https://wg21.link/p0826r0">SFINAE-friendly std::bind</a>. 12 October 2017. URL: <a href="https://wg21.link/p0826r0">https://wg21.link/p0826r0</a>
   <dt id="biblio-p0839r0">[P0839R0]
   <dd>Richard Smith. <a href="https://wg21.link/p0839r0">Recursive Lambdas</a>. 16 October 2017. URL: <a href="https://wg21.link/p0839r0">https://wg21.link/p0839r0</a>
   <dt id="biblio-p0847r0">[P0847R0]
   <dd>Gašper Ažman, Simon Brand, Ben Deane, Barry Revzin. <a href="https://wg21.link/p0847r0">Deducing this</a>. 12 February 2018. URL: <a href="https://wg21.link/p0847r0">https://wg21.link/p0847r0</a>
   <dt id="biblio-p0929r2">[P0929R2]
   <dd>Jens Maurer. <a href="https://wg21.link/p0929r2">Checking for abstract class types</a>. 6 June 2018. URL: <a href="https://wg21.link/p0929r2">https://wg21.link/p0929r2</a>
   <dt id="biblio-p1169r0">[P1169R0]
   <dd>Barry Revzin; Casey Carter. <a href="https://wg21.link/p1169r0">static operator()</a>. 7 October 2018. URL: <a href="https://wg21.link/p1169r0">https://wg21.link/p1169r0</a>
  </dl>