<!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>P1193R0: Explicitly Specified Returns for (Implicit) Conversions</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 7d8ce2d953ffaca8e344c0dab76f68fc292738a6" name="generator">
  <link href="https://isocpp.org/favicon.ico" rel="icon">
  <meta content="ba13c31ce1d3dca428223fcf2aa95f70c2c59827" name="document-revision">
<style>
pre {
  margin-top: 0px;
  margin-bottom: 0px;
}
.ins, ins, ins *, span.ins, span.ins * {
  background-color: rgb(200, 250, 200);
  color: rgb(0, 136, 0);
  text-decoration: underline;
}
.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);
}
math, span.math {
  font-family: serif;
  font-style: italic;
}
ul {
  list-style-type: "— ";
}
blockquote {
  counter-reset: paragraph;
}
div.numbered, div.newnumbered {
  margin-left: 2em;
  margin-top: 1em;
  margin-bottom: 1em;
}
div.numbered:before, div.newnumbered:before {
  position: absolute;
  margin-left: -2em;
  display-style: block;
}
div.numbered:before {
  content: counter(paragraph);
  counter-increment: paragraph;
}
div.newnumbered:before {
  content: "�";
}
div.numbered ul, div.newnumbered ul {
  counter-reset: list_item;
}
div.numbered li, div.newnumbered li {
  margin-left: 3em;
}
div.numbered li:before, div.newnumbered li:before {
  position: absolute;
  margin-left: -4.8em;
  display-style: block;
}
div.numbered li:before {
  content: "(" counter(paragraph) "." counter(list_item) ")";
  counter-increment: list_item;
}
div.newnumbered li:before {
  content: "(�." counter(list_item) ")";
  counter-increment: list_item;
}
</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">P1193R0<br>Explicitly Specified Returns for (Implicit) Conversions</h1>
   <h2 class="no-num no-toc no-ref heading settled" id="subtitle"><span class="content">Published Proposal, <time class="dt-updated" datetime="2018-11-26">2018-11-26</time></span></h2>
   <div data-fill-with="spec-metadata">
    <dl>
     <dt>Author:
     <dd>
      <dd class="editor p-author h-card vcard"><span class="p-name fn">JeanHeyd Meneide</span>
     <dt>Audience:
     <dd>EWG
     <dt>Project:
     <dd>ISO/IEC JTC1/SC22/WG21 14882: Programming Language — C++
     <dt>Latest:
     <dd><a href="https://thephd.github.io/vendor/future_cxx/papers/d1193.html">https://thephd.github.io/vendor/future_cxx/papers/d1193.html</a>
     <dt>Reply To:
     <dd><a href="mailto:phdofthehouse@gmail.com">JeanHeyd Meneide</a>, <a href="https://twitter.com/thephantomderp">@thephantomderp</a>
    </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>This paper proposes allowing a user to specify a return type to a conversion operator.</p>
  </div>
  <nav data-fill-with="table-of-contents" id="toc">
   <h2 class="no-num no-toc no-ref" id="contents">Table of Contents</h2>
   <ol class="toc" role="directory">
    <li>
     <a href="#changelog"><span class="secno">1</span> <span class="content">Revision History</span></a>
     <ol class="toc">
      <li><a href="#changelog-r0"><span class="secno">1.1</span> <span class="content">Revision 0 - November 26st, 2018</span></a>
     </ol>
    <li>
     <a href="#motivation"><span class="secno">2</span> <span class="content">Motivation</span></a>
     <ol class="toc">
      <li><a href="#motivation-readonly"><span class="secno">2.1</span> <span class="content">Read-Only</span></a>
      <li><a href="#motivation-mutual"><span class="secno">2.2</span> <span class="content">Mutual Exclusion</span></a>
      <li><a href="#motivation-general"><span class="secno">2.3</span> <span class="content">In General</span></a>
     </ol>
    <li>
     <a href="#design"><span class="secno">3</span> <span class="content">Design</span></a>
     <ol class="toc">
      <li><a href="#design-mechanism"><span class="secno">3.1</span> <span class="content">Mechanism</span></a>
      <li><a href="#design-syntax"><span class="secno">3.2</span> <span class="content">The Meanings and Syntax</span></a>
      <li><a href="#design-opt_in"><span class="secno">3.3</span> <span class="content">Opt-In</span></a>
      <li><a href="#design-infinity"><span class="secno">3.4</span> <span class="content">Okay, but what if I keep returning things that are convertible?</span></a>
     </ol>
    <li>
     <a href="#impact"><span class="secno">4</span> <span class="content">Impact</span></a>
     <ol class="toc">
      <li><a href="#impact-users"><span class="secno">4.1</span> <span class="content">On User Code</span></a>
      <li><a href="#impact-standard"><span class="secno">4.2</span> <span class="content">On the Standard</span></a>
     </ol>
    <li>
     <a href="#wording"><span class="secno">5</span> <span class="content">Proposed Wording and Feature Test Macros</span></a>
     <ol class="toc">
      <li><a href="#wording-feature"><span class="secno">5.1</span> <span class="content">Proposed Feature Test Macro</span></a>
      <li><a href="#wording-intent"><span class="secno">5.2</span> <span class="content">Intent</span></a>
      <li><a href="#wording-language"><span class="secno">5.3</span> <span class="content">Proposed Wording</span></a>
     </ol>
    <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>
   <table>
    <tbody>
     <tr>
      <th colspan="2">Shared Code 
     <tr>
      <td colspan="2">
<pre class="highlight"><c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-> <c- n>T</c-><c- o>></c->
<c- k>auto</c-> <c- n>make_some</c-><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- n>type_identity</c-><c- o>&lt;</c-><c- n>T</c-><c- o>></c-><c- p>)</c-> <c- p>{</c->
  <c- c1>// for exposition</c->
  <c- k>using</c-> <c- n>U</c-> <c- o>=</c-> <c- n>std</c-><c- o>::</c-><c- n>remove_const_t</c-><c- o>&lt;</c-><c- n>std</c-><c- o>::</c-><c- n>remove_reference_t</c-><c- o>&lt;</c-><c- n>T</c-><c- o>>></c-><c- p>;</c->
  <c- k>return</c-> <c- n>U</c-><c- p>{};</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- n>make_some</c-><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- n>type_identity</c-><c- o>&lt;</c-><c- n>std</c-><c- o>::</c-><c- n>tuple</c-><c- o>&lt;</c-><c- n>Args</c-><c- p>...</c-><c- o>>></c-><c- p>)</c-> <c- p>{</c->
  <c- k>return</c-> <c- n>std</c-><c- o>::</c-><c- n>tuple</c-><c- p>(</c-><c- n>make_some</c-><c- o>&lt;</c-><c- n>Args</c-><c- o>></c-><c- p>()...);</c->
<c- p>}</c->
</pre>
     <tr>
      <th>Currently
      <th>With Proposal
     <tr>
      <td>
<pre class="highlight"><c- k>struct</c-> <c- n>unicorn_proxy</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>operator</c-> <c- n>T</c-> <c- p>()</c-> <c- p>{</c->
    <c- k>return</c-> <c- n>make_some</c-><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- n>type_identity</c-><c- o>&lt;</c-><c- n>T</c-><c- o>></c-><c- p>());</c->
  <c- p>}</c->
<c- p>};</c->

<c- n>unicorn_proxy</c-> <c- n>u</c-><c- p>;</c->
<c- b>int</c-> <c- n>a</c-> <c- o>=</c-> <c- mi>24</c-><c- p>,</c-> <c- n>b</c-> <c- o>=</c-> <c- mi>3</c-><c- p>,</c-> <c- n>c</c-> <c- o>=</c-> <c- mi>2</c-><c- p>;</c->
<c- c1>// hard compiler error</c->
<c- n>std</c-><c- o>::</c-><c- n>tie</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- o>=</c-> <c- n>u</c-><c- p>;</c->
<c- n>assert</c-><c- p>(</c-><c- n>a</c-> <c- o>==</c-> <c- mi>0</c-><c- p>);</c->
<c- n>assert</c-><c- p>(</c-><c- n>b</c-> <c- o>==</c-> <c- mi>0</c-><c- p>);</c->
<c- n>assert</c-><c- p>(</c-><c- n>c</c-> <c- o>==</c-> <c- mi>0</c-><c- p>);</c->
</pre>
       🚫 compiler error: <code class="highlight"><c- n>could</c-> <c- n>not</c-> <c- n>convert</c-> '<c- n>make_some</c-><c- p>(...)</c->' <c- p>[</c-><c- n>with</c-> <c- n>Args</c-> <c- o>=</c-> <c- p>{</c-><c- b>int</c-><c- o>&amp;</c-><c- p>,</c-> <c- b>int</c-><c- o>&amp;</c-><c- p>,</c-> <c- b>int</c-><c- o>&amp;</c-><c- p>}]</c-> <c- n>from</c-> '<c- n>tuple</c-><c- o>&lt;</c-><c- b>int</c-><c- p>,</c-> <c- b>int</c-><c- p>,</c-> <c- b>int</c-><c- o>></c->' <c- n>to</c-> '<c- n>tuple</c-><c- o>&lt;</c-><c- b>int</c-><c- o>&amp;</c-><c- p>,</c-> <c- b>int</c-><c- o>&amp;</c-><c- p>,</c-> <c- b>int</c-><c- o>&amp;></c->'</code> 
      <td>
<pre class="highlight"><c- k>struct</c-> <c- n>unicorn_proxy</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- n>T</c-> <c- p>()</c-> <c- p>{</c->
    <c- k>return</c-> <c- n>make_some</c-><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- n>type_identity</c-><c- o>&lt;</c-><c- n>T</c-><c- o>></c-><c- p>());</c->
  <c- p>}</c->
<c- p>};</c->

<c- n>unicorn_proxy</c-> <c- n>u</c-><c- p>;</c->
<c- b>int</c-> <c- n>a</c-> <c- o>=</c-> <c- mi>24</c-><c- p>,</c-> <c- n>b</c-> <c- o>=</c-> <c- mi>3</c-><c- p>,</c-> <c- n>c</c-> <c- o>=</c-> <c- mi>2</c-><c- p>;</c->
<c- c1>// ta-da!~</c->
<c- n>std</c-><c- o>::</c-><c- n>tie</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- o>=</c-> <c- n>u</c-><c- p>;</c->
<c- n>assert</c-><c- p>(</c-><c- n>a</c-> <c- o>==</c-> <c- mi>0</c-><c- p>);</c->
<c- n>assert</c-><c- p>(</c-><c- n>b</c-> <c- o>==</c-> <c- mi>0</c-><c- p>);</c->
<c- n>assert</c-><c- p>(</c-><c- n>c</c-> <c- o>==</c-> <c- mi>0</c-><c- p>);</c->
</pre>
       ✔️ compiles, runs successfully 
   </table>
   <h2 class="heading settled" data-level="1" id="changelog"><span class="secno">1. </span><span class="content">Revision History</span><a class="self-link" href="#changelog"></a></h2>
   <h3 class="heading settled" data-level="1.1" id="changelog-r0"><span class="secno">1.1. </span><span class="content">Revision 0 - November 26st, 2018</span><a class="self-link" href="#changelog-r0"></a></h3>
   <p>Initial release.</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>There are many types which take advantage of certain conversion operations but need to have their type pinned down exactly in order for such conversions to work properly. We will review two cases here which speak to the heart of the problem: the "Read-Only" effect, and the "Mutual Exclusion" effect.</p>
   <h3 class="heading settled" data-level="2.1" id="motivation-readonly"><span class="secno">2.1. </span><span class="content">Read-Only</span><a class="self-link" href="#motivation-readonly"></a></h3>
   <p>A primary example is <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>tie</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-></code>, where it generates a tuple of references that expects any left-hand-side of the assignment operation to have types that can assign into each of the reference variables. This works with an explicit conversion:</p>
<pre class="highlight"><c- k>struct</c-> <c- n>fixed_proxy</c-> <c- p>{</c->
	<c- k>operator</c-> <c- n>std</c-><c- o>::</c-><c- n>tuple</c-><c- o>&lt;</c-><c- b>int</c-><c- p>,</c-> <c- b>int</c-><c- p>,</c-> <c- b>int</c-><c- o>></c-> <c- p>()</c-> <c- k>const</c-> <c- p>{</c->
		<c- k>return</c-> <c- n>std</c-><c- o>::</c-><c- n>make_tuple</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- p>}</c->
<c- p>};</c->

<c- b>int</c-> <c- n>a</c-><c- p>,</c-> <c- n>b</c-><c- p>,</c-> <c- n>c</c-><c- p>;</c->
<c- c1>// calls conversion operator</c->
<c- n>std</c-><c- o>::</c-><c- n>tie</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- o>=</c-> <c- n>fixed_proxy</c-><c- p>{};</c->
<c- c1>// a == 1, b == 2, c == 3</c->
</pre>
   <p>This breaks down when the type for the conversion operation is deduced. Consider a structure that is meant to be converted to anything that appears on the left hand side of an assignment expression or in any kind of constructor (an "omni" or "unicorn" proxy type):</p>
<pre class="highlight"><c- k>struct</c-> <c- n>unicorn_proxy</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>operator</c-> <c- n>T</c-> <c- p>()</c-> <c- p>{</c->
		<c- c1>// convert to some T</c->
		<c- c1>// we hardcore this here for example purposes,</c->
		<c- c1>// but usually comes from some make_some&lt;T>()</c->
		<c- c1>// function</c->
		<c- k>return</c-> <c- n>std</c-><c- o>::</c-><c- n>make_tuple</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- p>}</c->
<c- p>};</c->

<c- b>int</c-> <c- n>a</c-><c- p>,</c-> <c- n>b</c-><c- p>,</c-> <c- n>c</c-><c- p>;</c->
<c- c1>// compiler error</c->
<c- n>std</c-><c- o>::</c-><c- n>tie</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- o>=</c-> <c- n>unicorn_proxy</c-><c- p>{};</c->
</pre>
   <p>This is simply a hard compiler error, because <code class="highlight"><c- n>T</c-></code> is deduced to be <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>tuple</c-><c- o>&lt;</c-><c- b>int</c-><c- o>&amp;</c-><c- p>,</c-> <c- b>int</c-><c- o>&amp;</c-><c- p>,</c-> <c- b>int</c-><c- o>&amp;></c-></code>. Therefore, it becomes impossible to return newly constructed values into tuple, and effectively locks us out of participating in <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>tie</c-></code> or similar systems in C++. One would think they could perform some degree of result filtering or SFINAE to allow this to work. But, it does not:</p>
<pre class="highlight"><c- k>struct</c-> <c- n>unicorn_proxy</c-> <c- p>{</c->
	<c- c1>// compiler error</c->
	<c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-> <c- n>T</c-><c- o>></c->
	<c- k>operator</c-> <c- n>remove_internal_tuple_references_t</c-><c- o>&lt;</c-><c- n>T</c-><c- o>></c-> <c- p>();</c->
<c- p>};</c->
</pre>
   <p>This is also a hard compiler error, because only a potentially cv-qualified non-dependent type identifier is allowed by the grammar for the so-called "type argument" of a conversion member function.</p>
   <p>While developers can still apply SFINAE with enable_if and friends in the template, we cannot change the the type of <code class="highlight"><c- n>T</c-></code> itself. This is the essence of the "Read-Only" problem. Developers may query and utilize its properties, but the result -- the thing developers are interested in changing to play nice with <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>tie</c-></code> and other systems -- is an opaque black box that no one can touch.</p>
   <h3 class="heading settled" data-level="2.2" id="motivation-mutual"><span class="secno">2.2. </span><span class="content">Mutual Exclusion</span><a class="self-link" href="#motivation-mutual"></a></h3>
   <p>The mutual exclusion effect is very simple. Consider a type which is interested in the difference between a reference and a value (as is the case for <a href="https://github.com/ThePhD/sol2/issues/629">sol2’s proxy types</a>):</p>
<pre class="highlight"><c- k>struct</c-> <c- n>unicorn</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>operator</c-> <c- n>T</c-> <c- p>()</c-> <c- p>{</c->
        <c- k>static</c-> <c- n>std</c-><c- o>::</c-><c- n>decay_t</c-><c- o>&lt;</c-><c- n>T</c-><c- o>></c-> <c- n>v</c-> <c- o>=</c-> <c- n>std</c-><c- o>::</c-><c- n>decay_t</c-><c- o>&lt;</c-><c- n>T</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>operator</c-> <c- n>T</c-><c- o>&amp;</c-> <c- p>()</c-> <c- p>{</c->
        <c- k>static</c-> <c- n>std</c-><c- o>::</c-><c- n>decay_t</c-><c- o>&lt;</c-><c- n>T</c-><c- o>></c-> <c- n>v</c-> <c- o>=</c-> <c- n>std</c-><c- o>::</c-><c- n>decay_t</c-><c- o>&lt;</c-><c- n>T</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- n>unicorn</c-> <c- n>u</c-><c- p>;</c->
<c- b>int</c-> <c- n>i1</c-> <c- o>=</c-> <c- n>u</c-><c- p>;</c->
<c- b>int</c-><c- o>&amp;</c-> <c- n>i2</c-> <c- o>=</c-> <c- n>u</c-><c- p>;</c->
</pre>
   <p>The compiler will error here, stating that the conversion is ambiguous and that it cannot choose between either conversion operator:</p>
<pre class="highlight"><c- nl>error</c-><c- p>:</c-> <c- n>conversion</c-> <c- n>from</c-> '<c- n>unicorn</c->' <c- n>to</c-> '<c- b>int</c->' <c- n>is</c-> <c- n>ambiguous</c->
     <c- b>int</c-> <c- n>i1</c-> <c- o>=</c-> <c- n>u</c-><c- p>;</c->
	         <c- o>^</c->
</pre>
   <p>If the developer attempts to reduce it by removing the second conversion hoping that the first will be able to catch different reference types, the compiler will complain that it cannot initialize <code class="highlight"><c- n>i2</c-></code> properly:</p>
<pre class="highlight"><c- nl>error</c-><c- p>:</c-> <c- n>cannot</c-> <c- n>bind</c-> <c- n>non</c-><c- o>-</c-><c- k>const</c-> <c- n>lvalue</c-> <c- n>reference</c-> <c- n>of</c-> 
<c- n>type</c-> '<c- b>int</c-><c- o>&amp;</c->' <c- n>to</c-> <c- n>an</c-> <c- n>rvalue</c-> <c- n>of</c-> <c- n>type</c-> '<c- b>int</c->'
     <c- b>int</c-><c- o>&amp;</c-> <c- n>i2</c-> <c- o>=</c-> <c- n>u</c-><c- p>;</c->
	          <c- o>^</c->
</pre>
   <p>This means it is impossible to handle the difference between <code class="highlight"><c- b>int</c-><c- o>&amp;</c-></code> and <code class="highlight"><c- b>int</c-></code> for a single type during a conversion in C++. This happens with templated and non-templated conversion operators.</p>
   <h3 class="heading settled" data-level="2.3" id="motivation-general"><span class="secno">2.3. </span><span class="content">In General</span><a class="self-link" href="#motivation-general"></a></h3>
   <p>In general, C++'s conversion operators pick both the type and the result of an implicit conversion expression without letting the user perform any useful changes that they can normally perform with a regular function. It also does not let a single conversion operation handle different cv-qualified and ref-qualified types, leaving a very useful and specific class of conversions out. There are many cases where loosening the declaration, definition and usage of conversion operators would greatly benefit library and user code.</p>
   <p>Therefore, this paper proposes allowing the user to specify the return type of a conversion operation, and for templated conversion operations with an explicitly specified return type to be capable of capturing both a reference and value conversions similar to forwarded template parameters.</p>
   <h2 class="heading settled" data-level="3" id="design"><span class="secno">3. </span><span class="content">Design</span><a class="self-link" href="#design"></a></h2>
   <p>The primary design goal is to make the feature an entirely opt-in specification that interacts with the language in the same way regular conversions do, just with the compiler no longer assuming the return type is exactly the same as the type argument used to select the conversion operator. Here is an example of the full potential of a templated conversion operation with a changed return type:</p>
<pre class="highlight"><c- k>struct</c-> <c- n>new_unicorn_proxy</c-> <c- p>{</c->
	<c- c1>// capture anything</c->
	<c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-> <c- n>T</c-><c- o>></c->
	<c- k>decltype</c-><c- p>(</c-><c- k>auto</c-><c- p>)</c-> <c- k>operator</c-> <c- n>T</c-><c- o>&amp;&amp;</c-> <c- p>()</c-> <c- p>{</c->
		<c- c1>// ... return anything</c->
		<c- k>return</c-> <c- n>make_some</c-><c- o>&lt;</c-><c- n>std</c-><c- o>::</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- p>};</c->
</pre>
   <p>We go over the set of design decisions made for this extension to the language.</p>
   <h3 class="heading settled" data-level="3.1" id="design-mechanism"><span class="secno">3.1. </span><span class="content">Mechanism</span><a class="self-link" href="#design-mechanism"></a></h3>
   <p>Allowing an implicit conversion to return different types and deduce reference qualifiers alongside cv-qualifiers opens up a few unique opportunities. The anatomy of this proposal is: <code class="highlight"><c- n>return_type</c-> <c- k>operator</c-> <c- nf>type_argument</c-> <c- p>();</c-></code>.</p>
   <h3 class="heading settled" data-level="3.2" id="design-syntax"><span class="secno">3.2. </span><span class="content">The Meanings and Syntax</span><a class="self-link" href="#design-syntax"></a></h3>
   <p>Enabling explicit returns comes with a few interesting design decisions when it comes to the syntax and the meanings. Thankfully, the change is wholly conservative and does not complicate or change the grammar with any new keywords or terminology. There is a difference in semantics, however, which is why it is incredibly important that this feature is <a href="#design-opt_in">§3.3 Opt-In</a>:</p>
<pre class="highlight"><c- k>struct</c-> <c- n>unicorn_value</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- n>T</c-> <c- p>();</c->
<c- p>};</c->

<c- k>struct</c-> <c- n>unicorn_ref</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- n>T</c-><c- o>&amp;</c-> <c- p>();</c->
<c- p>};</c->
</pre>
   <p>The above two behave like they always do: no matter what you decorate the left hand side of your expression with, it will always deduce <code class="highlight"><c- n>T</c-></code> to be the type without reference qualifiers. However, with the new syntax we introduce a distinction between the old form and the new form:</p>
<pre class="highlight"><c- k>struct</c-> <c- n>unicorn_anything</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- n>T</c-><c- o>&amp;&amp;</c-> <c- p>();</c->
<c- p>};</c->
</pre>
   <p>This conversion operator in particular does not work with only r-value references as the previous form did: <code class="highlight"><c- n>T</c-></code> will deduce to exactly the type of the expression on the left hand side, including all cv-qualifiers and reference qualifiers. This only happens when you <a href="#design-opt_in">§3.3 Opt-In</a> to this feature by adding a return type.</p>
   <p>The reason for this departure is as explained before. The <a href="#motivation-mutual">§2.2 Mutual Exclusion</a> problem removes classes of code that care about a single type that can be an l-value, an r-value, or just a plain value in C++ code. By allowing a type argument that has the same capture rules as a forwarding reference, we can capture these differences and act on them in code.</p>
   <p>Similarly, allowing us to manipulate the return type more thoroughly allows us to handle the <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>tie</c-></code> and similar problems. Note that this does not actually change the rules for user-defined conversions as they are now by much: the compiler selects which overload is appropriate by using the type argument -- templated or not -- and passes that return value back. If the return value can construct or be used with what the compiler has selected, that is fine. If it cannot, then it will issue a diagnostic (in the same way that the return type of an overloaded function was used incorrectly).</p>
   <h3 class="heading settled" data-level="3.3" id="design-opt_in"><span class="secno">3.3. </span><span class="content">Opt-In</span><a class="self-link" href="#design-opt_in"></a></h3>
   <p>Any language feature that wants to minimize potential problems and breakage must be opt-in. The syntax we require for our extension is entirely opt-in, and does not affect previous declarations.</p>
   <p>The meaning of old code does not change, and neither does the way it interacts with any of the code currently existing in the codebase. Old code continues to be good code, and this mechanism remains in the standard because it is usually what an individual wants to begin with: it can simply be seen as the compact version of the extension we are attempting to provide. Using the new syntax for an explicit return value does not actually change what, e.g. <code class="highlight"><c- n>T</c-></code> would deduce to in the above case for the <code class="highlight"><c- n>new_unicorn_proxy</c-></code>.</p>
   <h3 class="heading settled" data-level="3.4" id="design-infinity"><span class="secno">3.4. </span><span class="content">Okay, but what if I keep returning things that are convertible?</span><a class="self-link" href="#design-infinity"></a></h3>
   <p>This is already banned under current rules: all user-defined conversions to non-built-in types may only go through 1 conversion resolution, otherwise the conversion is ill-formed as defined by <a href="http://eel.is/c++draft/class.conv.fct">class.conv.fct, clause 4</a>. Clause 1 of the same also forbids returning the same type as the object the conversion being performed on or the base class.</p>
   <p>The same rule still holds: conversions are not allowed to return the same type as the type the conversion is being invoked on (or any of its base classes). The type returned shall also be usable in the context that it is selected in. This means that a conversion that uses a type argument of <code class="highlight"><c- b>int</c-></code> must return a type that is convertible to <code class="highlight"><c- b>int</c-></code> without further user defined conversions (but may invoke additional constructors or other overloaded functions based on the selection).</p>
   <p>This rule is stringent to fit how strict the current lookup model is (one and only one user defined conversion to non-built-in type per resolution attempt). There may be room to relax the rules to allow more flexibility if the return type is not identical to the type argument, but this proposal does not explore this avenue at this time. It would be more prudent to establish this feature, and then look at the potential extension of this to behave more closely to something like e.g. <code class="highlight"><c- k>operator</c-><c- o>-></c-></code>. However, this kind of change would require a breaking change to existing code since the behavior would change and fundamentally affects the purely opt-in nature of this proposed change.</p>
   <h2 class="heading settled" data-level="4" id="impact"><span class="secno">4. </span><span class="content">Impact</span><a class="self-link" href="#impact"></a></h2>
   <p>Since this feature has been designed to be <a href="#design-opt_in">§3.3 Opt-In</a>, the impact is absolutely minimal.</p>
   <h3 class="heading settled" data-level="4.1" id="impact-users"><span class="secno">4.1. </span><span class="content">On User Code</span><a class="self-link" href="#impact-users"></a></h3>
   <p>While this introduces an extension to a previous language construct, it thankfully does not break any old code due to its opt-in nature. This is a very important design aspect of this extension syntax: it cannot and should not break any old code unless someone explicitly opts into the functionality. At that point, the potential breakage is still completely bounded, because the return type a developer chooses for a conversion operator member is up to them.</p>
   <h3 class="heading settled" data-level="4.2" id="impact-standard"><span class="secno">4.2. </span><span class="content">On the Standard</span><a class="self-link" href="#impact-standard"></a></h3>
   <p>This does not cause any breakages in the Standard Library or with existing code. No facilities in the standard library would need to use this facility currently.</p>
   <h2 class="heading settled" data-level="5" id="wording"><span class="secno">5. </span><span class="content">Proposed Wording and Feature Test Macros</span><a class="self-link" href="#wording"></a></h2>
   <p><strong>This wording section needs help!</strong> Any help anyone can give to properly process the wording for this section would be greatly appreciated; this wording is done by the author, who is a novice in parsing and producing Standardese suitable for Core Working Group consumption. The following wording is relative to <a data-link-type="biblio" href="#biblio-n4762">[n4762]</a>.</p>
   <h3 class="heading settled" data-level="5.1" id="wording-feature"><span class="secno">5.1. </span><span class="content">Proposed Feature Test Macro</span><a class="self-link" href="#wording-feature"></a></h3>
   <p>The recommended feature test macro is <code class="highlight"><c- n>__cpp_conversion_return_types</c-></code>.</p>
   <h3 class="heading settled" data-level="5.2" id="wording-intent"><span class="secno">5.2. </span><span class="content">Intent</span><a class="self-link" href="#wording-intent"></a></h3>
   <p>The intent of this proposed wording is to allow for an explicit return type to be optionally defined on a member conversion operator. In particular, this proposal wants to:</p>
   <ul>
    <li data-md>
     <p>add grammar to allow for a second <code class="highlight"><c- n>conversion</c-><c- o>-</c-><c- n>type</c-><c- o>-</c-><c- n>id</c-></code> to precede the <code class="highlight"><c- k>operator</c-></code> keyword;</p>
    <li data-md>
     <p>allow the preceding <code class="highlight"><c- n>conversion</c-><c- o>-</c-><c- n>type</c-><c- o>-</c-><c- n>id</c-></code> to be the return type and the mandatory following <code class="highlight"><c- n>conversion</c-><c- o>-</c-><c- n>type</c-><c- o>-</c-><c- n>id</c-></code> to be the type argument;</p>
    <li data-md>
     <p>allow for deduced return types to be explicitly marked with <code class="highlight"><c- k>decltype</c-><c- p>(</c-><c- k>auto</c-><c- p>)</c-></code> and <code class="highlight"><c- k>auto</c-></code> by having an explicit return, templated or not;</p>
    <li data-md>
     <p>create a new feature test macro for detecting if this language functionality exists;</p>
    <li data-md>
     <p>and, add illustrating examples to aid implementers in the desired outcome of the new feature.</p>
   </ul>
   <p>Notably, function and array type names are still not allowed as the <code class="highlight"><c- n>conversion</c-><c- o>-</c-><c- n>type</c-><c- o>-</c-><c- n>id</c-></code> following the operator. If it is deemed appropriate to allow function type and array return types so long as the <code class="highlight"><c- n>conversion</c-><c- o>-</c-><c- n>type</c-><c- o>-</c-><c- n>id</c-></code> is still within the bounds of class conversion function’s clause 3 [<a href="http://eel.is/c++draft/class.conv.fct">class.conv.fct</a>] restrictions, this can be added in.</p>
   <h3 class="heading settled" data-level="5.3" id="wording-language"><span class="secno">5.3. </span><span class="content">Proposed Wording</span><a class="self-link" href="#wording-language"></a></h3>
   <p>Modify §10.3.8.2 [<strong>class.conv.fct</strong>], clause 1 to read as follows:</p>
   <blockquote>
    <p><sup>1</sup>A member function of a class X having no parameters with a declarator-id of <code class="highlight"><c- k>operator</c-></code> and of the form </p>
    <dl>
     <dt><i>conversion-function-id</i>:
     <dd>operator <i>conversion-type-id</i>
     <dt><i>conversion-type-id</i>:
     <dd><i>type-specifier-seq</i> <i>conversion-declarator<sub>opt</sub></i>
     <dt><i>conversion-declarator</i>:
     <dd><i>ptr-operator</i> <i>conversion-declarator<sub>opt</sub></i>
    </dl>
    <p>
     specifies a conversion from X to the type specified by the 
     <ins>trailing </ins>
     <i>conversion-type-id</i>. Such functions are called conversion functions. A <i>decl-specifier</i> in the <i>decl-specifier-seq</i> of a conversion function (if any) shall
     <ins> not</ins>
      be 
     <del>neither a <i>defining-type-specifier</i> nor </del>
     <code class="highlight"><c- k>static</c-></code>. The type of the conversion function (<a href="http://eel.is/c++draft/dcl.fct">[dcl.fct]</a>) is “function taking no parameter returning <i>conversion-type-id</i>”
     <ins> or “function taking no parameter returning <i>decl-specifier-seq</i>”</ins>
     . A conversion function is never used to convert a (possibly cv-qualified) object to the (possibly cv-qualified) same object type (or a reference to it), to a (possibly cv-qualified) base class of that type (or a reference to it), or to (possibly cv-qualified) void.<sup>112</sup> [ <i>Example:</i>
    </p>
<pre class="highlight"><code class="highlight"><c- k><c- k>struct</c-></c-> <c- n><c- n>X</c-></c-> <c- p><c- p>{</c-></c->
  <c- k><c- k>operator</c-></c-> <c- b><c- b>int</c-></c-><c- p><c- p>();</c-></c->
  <c- k><c- k>operator</c-></c-> <c- nf><c- nf>auto</c-></c-><c- p><c- p>()</c-></c-> <c- o><c- o>-></c-></c-> <c- b><c- b>short</c-></c-><c- p><c- p>;</c-></c-> <c- c1><c- c1>// error: trailing return type</c-></c-><ins><c- c1><c- c1> without </c-></c-><i><c- c1><c- c1>decl-specifier-seq</c-></c-></i></ins>
<c- p><c- p>};</c-></c->

<c- b><c- b>void</c-></c-> <c- nf><c- nf>f</c-></c-><c- p><c- p>(</c-></c-><c- n><c- n>X</c-></c-> <c- n><c- n>a</c-></c-><c- p><c- p>)</c-></c-> <c- p><c- p>{</c-></c->
  <c- b><c- b>int</c-></c-> <c- n><c- n>i</c-></c-> <c- o><c- o>=</c-></c-> <c- b><c- b>int</c-></c-><c- p><c- p>(</c-></c-><c- n><c- n>a</c-></c-><c- p><c- p>);</c-></c->
  <c- n><c- n>i</c-></c-> <c- o><c- o>=</c-></c-> <c- p><c- p>(</c-></c-><c- b><c- b>int</c-></c-><c- p><c- p>)</c-></c-><c- n><c- n>a</c-></c-><c- p><c- p>;</c-></c->
  <c- n><c- n>i</c-></c-> <c- o><c- o>=</c-></c-> <c- n><c- n>a</c-></c-><c- p><c- p>;</c-></c->
<c- p><c- p>}</c-></c->
</code></pre>
    <p>In all three cases the value assigned will be converted by X::operator int(). — <i>end example</i> ]</p>
    <p>[ <i>Example:</i></p>
<pre class="highlight"><code class="highlight"><c- k><c- k>struct</c-></c-> <c- n><c- n>X</c-></c-> <c- p><c- p>{</c-></c->
  <c- k><c- k>auto</c-></c-> <c- k><c- k>operator</c-></c-> <c- b><c- b>double</c-></c-><c- p><c- p>()</c-></c-> <c- o><c- o>-></c-></c-> <c- b><c- b>int</c-></c-><c- p><c- p>;</c-></c-> <c- c1><c- c1>// OK: </c-></c-><i><c- c1><c- c1>decl-specifier-seq</c-></c-></i><c- c1><c- c1> allows deduction</c-></c->
  <c- b><c- b>char</c-></c-><c- o><c- o>*</c-></c-> <c- k><c- k>operator</c-></c-> <c- b><c- b>void</c-></c-><c- o><c- o>*</c-></c-><c- p><c- p>();</c-></c->
<c- p><c- p>};</c-></c->

<c- b><c- b>void</c-></c-> <c- nf><c- nf>f</c-></c-><c- p><c- p>(</c-></c-><c- n><c- n>X</c-></c-> <c- n><c- n>a</c-></c-><c- p><c- p>)</c-></c-> <c- p><c- p>{</c-></c->
  <c- b><c- b>double</c-></c-> <c- n><c- n>di</c-></c-> <c- o><c- o>=</c-></c-> <c- n><c- n>a</c-></c-><c- p><c- p>;</c-></c-> <c- c1><c- c1>// selects first conversion</c-></c->
  <c- b><c- b>float</c-></c-> <c- n><c- n>fi</c-></c-> <c- o><c- o>=</c-></c-> <c- n><c- n>a</c-></c-><c- p><c- p>;</c-></c-> <c- c1><c- c1>// selects first conversion</c-></c->
  <c- b><c- b>void</c-></c-><c- o><c- o>*</c-></c-> <c- n><c- n>from_char_ptr</c-></c-> <c- o><c- o>=</c-></c-> <c- n><c- n>a</c-></c-><c- p><c- p>;</c-></c-> <c- c1><c- c1>// selects second conversion</c-></c->
  <c- b><c- b>char</c-></c-><c- o><c- o>*</c-></c-> <c- n><c- n>char_ptr</c-></c-> <c- o><c- o>=</c-></c-> <c- n><c- n>a</c-></c-><c- p><c- p>;</c-></c-> <c- c1><c- c1>// error: no matching conversion to char*</c-></c->
<c- p><c- p>}</c-></c->
</code></pre>
    <p>When the <i>conversion-type-id</i> and <i>decl-specifier-seq</i> are both present, the implementation shall pick the <i>decl-specifier-seq</i> as the return type but use the <i>conversion-type-id</i> as the selection criteria for the conversion and overloading therein  ([<a href="http://eel.is/c++draft/over.best.ics">over.best.ics</a>], [<a href="http://eel.is/c++draft/over.ics.ref">over.ics.ref</a>]). In this case, the <i>decl-specifier-seq</i> of <code class="highlight"><c- b>char</c-><c- o>*</c-></code> for the second conversion does not affect overload resolution.  — <i>end example</i> ]</p>
   </blockquote>
   <p>Modify §10.3.8.2 [<strong>class.conv.fct</strong>], clause 6 to read as follows:</p>
   <blockquote>
     <sup>6</sup> A conversion function template shall not have a deduced return type ([<a href="http://eel.is/c++draft/dcl.spec.auto">dcl.spec.auto</a>]) 
    <ins>specified by its <i>conversion-type-id</i> without a <i>decl-specifier-seq</i></ins>
    .
[ <i>Example:</i> 
<pre class="highlight"><code class="highlight"><c- k><c- k>struct</c-></c-> <c- n><c- n>S</c-></c-> <c- p><c- p>{</c-></c->
  <c- k><c- k>operator</c-></c-> <c- k><c- k>auto</c-></c-><c- p><c- p>()</c-></c-> <c- k><c- k>const</c-></c-> <c- p><c- p>{</c-></c-> <c- k><c- k>return</c-></c-> <c- mi><c- mi>10</c-></c-><c- p><c- p>;</c-></c-> <c- p><c- p>}</c-></c->           <c- c1><c- c1>// OK</c-></c->
  <c- k><c- k>template</c-></c-><c- o><c- o>&lt;</c-></c-><c- k><c- k>class</c-></c-> <c- nc><c- nc>T</c-></c-><c- o><c- o>></c-></c->
  <c- k><c- k>operator</c-></c-> <c- k><c- k>auto</c-></c-><c- p><c- p>()</c-></c-> <c- k><c- k>const</c-></c-> <c- p><c- p>{</c-></c-> <c- k><c- k>return</c-></c-> <c- mf><c- mf>1.2</c-></c-><c- p><c- p>;</c-></c-> <c- p><c- p>}</c-></c->          <c- c1><c- c1>// error: conversion function template</c-></c->
<ins>  <c- k><c- k>template</c-></c-><c- o><c- o>&lt;</c-></c-><c- k><c- k>class</c-></c-> <c- nc><c- nc>T</c-></c-><c- o><c- o>></c-></c->
  <c- k><c- k>auto</c-></c-> <c- k><c- k>operator</c-></c-> <c- n><c- n>T</c-></c-><c- p><c- p>()</c-></c-> <c- k><c- k>const</c-></c-> <c- p><c- p>{</c-></c-> <c- k><c- k>return</c-></c-> <c- s><c- s>"bjork"</c-></c-><c- p><c- p>;</c-></c-> <c- p><c- p>}</c-></c->    <c- c1><c- c1>// OK</c-></c-></ins>
<c- p><c- p>};</c-></c->
</code></pre>
    <p>— <i>end example</i> ]</p>
   </blockquote>
   <p>Append to §14.8.1 Predefined macro names [<strong>cpp.predefined</strong>]'s <strong>Table 16</strong> with one additional entry:</p>
   <blockquote>
    <table>
     <tbody>
      <tr>
       <th>Macro name
       <th>Value
      <tr>
       <td>
        <ins>__cpp_conversion_return_types</ins>
       <td>
        <ins>201811L</ins>
    </table>
   </blockquote>
   <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>Thank you to Lisa Lippincott for the advice and knowledge on how to solve this problem in an elegant and simple manner.</p>
  </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-n4762">[N4762]
   <dd>ISO/IEC JTC1/SC22/WG21 - The C++ Standards Committee; Richard Smith. <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/n4762.pdf">N4762 - Working Draft, Standard for Programming Language C++</a>. May 7th, 2018. URL: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/n4762.pdf">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/n4762.pdf</a>
  </dl>