<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>explicit(bool)</title>

<style type="text/css">html {
	position: relative;
	max-width: 1024px;
	height: 100%;
}
body {
	font-family: Helvetica, arial, sans-serif;
	font-size: 14px;
	line-height: 1.6;
	padding-top: 10px;
	padding-bottom: 10px;
	background-color: white;
	padding: 30px;
}
body>*:first-child {
	margin-top: 0 !important;
}
body>*:last-child {
	margin-bottom: 0 !important;
}
a {
	color: #4183C4;
}
a.absent {
	color: #cc0000;
}
a.anchor {
	display: block;
	padding-left: 30px;
	margin-left: -30px;
	cursor: pointer;
	position: absolute;
	top: 0;
	left: 0;
	bottom: 0;
}
h1, h2, h3, h4, h5, h6 {
	margin: 20px 0 10px;
	padding: 0;
	font-weight: bold;
	-webkit-font-smoothing: antialiased;
	cursor: text;
	position: relative;
}
h1:hover a.anchor, h2:hover a.anchor, h3:hover a.anchor, h4:hover a.anchor, h5:hover a.anchor, h6:hover a.anchor {
	background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA09pVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoMTMuMCAyMDEyMDMwNS5tLjQxNSAyMDEyLzAzLzA1OjIxOjAwOjAwKSAgKE1hY2ludG9zaCkiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6OUM2NjlDQjI4ODBGMTFFMTg1ODlEODNERDJBRjUwQTQiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6OUM2NjlDQjM4ODBGMTFFMTg1ODlEODNERDJBRjUwQTQiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo5QzY2OUNCMDg4MEYxMUUxODU4OUQ4M0REMkFGNTBBNCIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo5QzY2OUNCMTg4MEYxMUUxODU4OUQ4M0REMkFGNTBBNCIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PsQhXeAAAABfSURBVHjaYvz//z8DJYCRUgMYQAbAMBQIAvEqkBQWXI6sHqwHiwG70TTBxGaiWwjCTGgOUgJiF1J8wMRAIUA34B4Q76HUBelAfJYSA0CuMIEaRP8wGIkGMA54bgQIMACAmkXJi0hKJQAAAABJRU5ErkJggg==) no-repeat 10px center;
	text-decoration: none;
}
h1 tt, h1 code {
	font-size: inherit;
}
h2 tt, h2 code {
	font-size: inherit;
}
h3 tt, h3 code {
	font-size: inherit;
}
h4 tt, h4 code {
	font-size: inherit;
}
h5 tt, h5 code {
	font-size: inherit;
}
h6 tt, h6 code {
	font-size: inherit;
}
h1 {
	font-size: 28px;
	color: black;
}
h2 {
	font-size: 24px;
	border-bottom: 1px solid #cccccc;
	color: black;
}
h3 {
	font-size: 18px;
}
h4 {
	font-size: 16px;
}
h5 {
	font-size: 14px;
}
h6 {
	color: #777777;
	font-size: 14px;
}
p, blockquote, ol, dl, li, table, pre {
	margin: 15px 0;
}
hr {
	background: transparent url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAYAAAAECAYAAACtBE5DAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBNYWNpbnRvc2giIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6OENDRjNBN0E2NTZBMTFFMEI3QjRBODM4NzJDMjlGNDgiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6OENDRjNBN0I2NTZBMTFFMEI3QjRBODM4NzJDMjlGNDgiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo4Q0NGM0E3ODY1NkExMUUwQjdCNEE4Mzg3MkMyOUY0OCIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo4Q0NGM0E3OTY1NkExMUUwQjdCNEE4Mzg3MkMyOUY0OCIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PqqezsUAAAAfSURBVHjaYmRABcYwBiM2QSA4y4hNEKYDQxAEAAIMAHNGAzhkPOlYAAAAAElFTkSuQmCC) repeat-x 0 0;
	border: 0 none;
	color: #cccccc;
	height: 4px;
	padding: 0;
}
body>h2:first-child {
	margin-top: 0;
	padding-top: 0;
}
body>h1:first-child {
	margin-top: 0;
	padding-top: 0;
}
body>h1:first-child+h2 {
	margin-top: 0;
	padding-top: 0;
}
body>h3:first-child, body>h4:first-child, body>h5:first-child, body>h6:first-child {
	margin-top: 0;
	padding-top: 0;
}
a:first-child h1, a:first-child h2, a:first-child h3, a:first-child h4, a:first-child h5, a:first-child h6 {
	margin-top: 0;
	padding-top: 0;
}
h1 p, h2 p, h3 p, h4 p, h5 p, h6 p {
	margin-top: 0;
}
li p.first {
	display: inline-block;
}
li {
	margin: 0;
}
ol {
	padding-left: 30px;
}
ul :first-child, ol :first-child {
	margin-top: 0;
}
dl {
	padding: 0;
}
dl dt {
	font-size: 14px;
	font-weight: bold;
	font-style: italic;
	padding: 0;
	margin: 15px 0 5px;
}
dl dt:first-child {
	padding: 0;
}
dl dt> :first-child {
	margin-top: 0;
}
dl dt> :last-child {
	margin-bottom: 0;
}
dl dd {
	margin: 0 0 15px;
	padding: 0 15px;
}
dl dd> :first-child {
	margin-top: 0;
}
dl dd> :last-child {
	margin-bottom: 0;
}
blockquote {
	border-left: 4px solid #dddddd;
	padding: 0 15px;
	color: #777777;
}
blockquote> :first-child {
	margin-top: 0;
}
blockquote> :last-child {
	margin-bottom: 0;
}
table {
	padding: 0;
	border-collapse: collapse;
}
table tr {
	border-top: 1px solid #cccccc;
	background-color: white;
	margin: 0;
	padding: 0;
}
table tr:nth-child(2n) {
	background-color: #f8f8f8;
}
table tr th {
	font-weight: bold;
	border: 1px solid #cccccc;
	margin: 0;
	padding: 6px 13px;
}
table tr td {
	border: 1px solid #cccccc;
	margin: 0;
	padding: 6px 13px;
}
table tr th :first-child, table tr td :first-child {
	margin-top: 0;
}
table tr th :last-child, table tr td :last-child {
	margin-bottom: 0;
}
td {
	vertical-align: top;
}
img {
	max-width: 100%;
}
span.frame {
	display: block;
	overflow: hidden;
}
span.frame>span {
	border: 1px solid #dddddd;
	display: block;
	float: left;
	overflow: hidden;
	margin: 13px 0 0;
	padding: 7px;
	width: auto;
}
span.frame span img {
	display: block;
	float: left;
}
span.frame span span {
	clear: both;
	color: #333333;
	display: block;
	padding: 5px 0 0;
}
span.align-center {
	display: block;
	overflow: hidden;
	clear: both;
}
span.align-center>span {
	display: block;
	overflow: hidden;
	margin: 13px auto 0;
	text-align: center;
}
span.align-center span img {
	margin: 0 auto;
	text-align: center;
}
span.align-right {
	display: block;
	overflow: hidden;
	clear: both;
}
span.align-right>span {
	display: block;
	overflow: hidden;
	margin: 13px 0 0;
	text-align: right;
}
span.align-right span img {
	margin: 0;
	text-align: right;
}
span.float-left {
	display: block;
	margin-right: 13px;
	overflow: hidden;
	float: left;
}
span.float-left span {
	margin: 13px 0 0;
}
span.float-right {
	display: block;
	margin-left: 13px;
	overflow: hidden;
	float: right;
}
span.float-right>span {
	display: block;
	overflow: hidden;
	margin: 13px auto 0;
	text-align: right;
}
code, tt {
	margin: 0 2px;
	padding: 0 5px;
	white-space: nowrap;
	border: 1px solid #eaeaea;
	background-color: #f8f8f8;
	border-radius: 3px;
}
pre code {
	margin: 0;
	padding: 0;
	white-space: pre;
	border: none;
	background: transparent;
}
.highlight pre {
	background-color: #f8f8f8;
	border: 1px solid #cccccc;
	font-size: 13px;
	line-height: 19px;
	overflow: auto;
	padding: 6px 10px;
	border-radius: 3px;
}
pre {
	background-color: #f8f8f8;
	border: 1px solid #cccccc;
	font-size: 13px;
	line-height: 19px;
	overflow: auto;
    overflow-x: hidden;
    overflow-y: hidden;
	padding: 6px 10px;
	border-radius: 3px;
}
pre code, pre tt {
	background-color: transparent;
	border: none;
}
sup {
	font-size: 0.83em;
	vertical-align: super;
	line-height: 0;
}
kbd {
	display: inline-block;
	padding: 3px 5px;
	font-size: 11px;
	line-height: 10px;
	color: #555;
	vertical-align: middle;
	background-color: #fcfcfc;
	border: solid 1px #ccc;
	border-bottom-color: #bbb;
	border-radius: 3px;
	box-shadow: inset 0 -1px 0 #bbb
}
* {
	-webkit-print-color-adjust: exact;
}
ins {
	color: #00A000
}
del {
	color: #A00000
}
</style><style type="text/css">
/**
	* prism.js default theme for JavaScript, CSS and HTML
	* Based on dabblet (http://dabblet.com)
	* @author Lea Verou
	*/

code[class*="language-"], pre[class*="language-"] {
	color: black;
	background: none;
	text-shadow: 0 1px white;
	font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
	font-size: 11px;
	text-align: left;
	white-space: pre;
	word-spacing: normal;
	word-break: normal;
	word-wrap: normal;
	line-height: 1.5;
	-moz-tab-size: 4;
	-o-tab-size: 4;
	tab-size: 4;
	-webkit-hyphens: none;
	-moz-hyphens: none;
	-ms-hyphens: none;
	hyphens: none;
}
pre[class*="language-"]::-moz-selection, pre[class*="language-"] ::-moz-selection, code[class*="language-"]::-moz-selection, code[class*="language-"] ::-moz-selection {
	text-shadow: none;
	background: #b3d4fc;
}
pre[class*="language-"]::selection, pre[class*="language-"] ::selection, code[class*="language-"]::selection, code[class*="language-"] ::selection {
	text-shadow: none;
	background: #b3d4fc;
}
@media print {
	code[class*="language-"], pre[class*="language-"] {
		text-shadow: none;
	}
}

/* Code blocks */

pre[class*="language-"] {
	padding: 1em;
	margin: .5em 0;
	overflow: auto;
    overflow-x: hidden;
    overflow-y: hidden;
}
:not(pre)>code[class*="language-"], pre[class*="language-"] {
	background: #f8f8f8;
}

/* Inline code */

:not(pre)>code[class*="language-"] {
	padding: .1em;
	border-radius: .3em;
	white-space: normal;
}
.token.comment, .token.prolog, .token.doctype, .token.cdata {
	color: slategray;
}
.token.punctuation {
	color: #999;
}
.namespace {
	opacity: .7;
}
.token.property, .token.tag, .token.boolean, .token.number, .token.constant, .token.symbol, .token.deleted {
	color: #905;
}
.token.selector, .token.attr-name, .token.string, .token.char, .token.builtin, .token.inserted {
	color: #690;
}
.token.operator {
	color: #a67f59;
}
.token.entity, .token.url, .language-css .token.string, .style .token.string {
	color: #a67f59;
	background: hsla(0, 0%, 100%, .5);
}
.token.atrule, .token.attr-value, .token.keyword {
	color: #07a;
}
.token.function {
	color: #DD4A68;
}
.token.regex, .token.important, .token.variable {
	color: #e90;
}
.token.important, .token.bold {
	font-weight: bold;
}
.token.italic {
	font-style: italic;
}
.token.entity {
	cursor: help;
}
</style>

<script type="text/javascript">
var _self="undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{},Prism=function(){var e=/\blang(?:uage)?-(\w+)\b/i,t=0,n=_self.Prism={util:{encode:function(e){return e instanceof a?new a(e.type,n.util.encode(e.content),e.alias):"Array"===n.util.type(e)?e.map(n.util.encode):e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/\u00a0/g," ")},type:function(e){return Object.prototype.toString.call(e).match(/\[object (\w+)\]/)[1]},objId:function(e){return e.__id||Object.defineProperty(e,"__id",{value:++t}),e.__id},clone:function(e){var t=n.util.type(e);switch(t){case"Object":var a={};for(var r in e)e.hasOwnProperty(r)&&(a[r]=n.util.clone(e[r]));return a;case"Array":return e.map&&e.map(function(e){return n.util.clone(e)})}return e}},languages:{extend:function(e,t){var a=n.util.clone(n.languages[e]);for(var r in t)a[r]=t[r];return a},insertBefore:function(e,t,a,r){r=r||n.languages;var l=r[e];if(2==arguments.length){a=arguments[1];for(var i in a)a.hasOwnProperty(i)&&(l[i]=a[i]);return l}var o={};for(var s in l)if(l.hasOwnProperty(s)){if(s==t)for(var i in a)a.hasOwnProperty(i)&&(o[i]=a[i]);o[s]=l[s]}return n.languages.DFS(n.languages,function(t,n){n===r[e]&&t!=e&&(this[t]=o)}),r[e]=o},DFS:function(e,t,a,r){r=r||{};for(var l in e)e.hasOwnProperty(l)&&(t.call(e,l,e[l],a||l),"Object"!==n.util.type(e[l])||r[n.util.objId(e[l])]?"Array"!==n.util.type(e[l])||r[n.util.objId(e[l])]||(r[n.util.objId(e[l])]=!0,n.languages.DFS(e[l],t,l,r)):(r[n.util.objId(e[l])]=!0,n.languages.DFS(e[l],t,null,r)))}},plugins:{},highlightAll:function(e,t){var a={callback:t,selector:'code[class*="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code'};n.hooks.run("before-highlightall",a);for(var r,l=a.elements||document.querySelectorAll(a.selector),i=0;r=l[i++];)n.highlightElement(r,e===!0,a.callback)},highlightElement:function(t,a,r){for(var l,i,o=t;o&&!e.test(o.className);)o=o.parentNode;o&&(l=(o.className.match(e)||[,""])[1],i=n.languages[l]),t.className=t.className.replace(e,"").replace(/\s+/g," ")+" language-"+l,o=t.parentNode,/pre/i.test(o.nodeName)&&(o.className=o.className.replace(e,"").replace(/\s+/g," ")+" language-"+l);var s=t.textContent,u={element:t,language:l,grammar:i,code:s};if(!s||!i)return n.hooks.run("complete",u),void 0;if(n.hooks.run("before-highlight",u),a&&_self.Worker){var c=new Worker(n.filename);c.onmessage=function(e){u.highlightedCode=e.data,n.hooks.run("before-insert",u),u.element.innerHTML=u.highlightedCode,r&&r.call(u.element),n.hooks.run("after-highlight",u),n.hooks.run("complete",u)},c.postMessage(JSON.stringify({language:u.language,code:u.code,immediateClose:!0}))}else u.highlightedCode=n.highlight(u.code,u.grammar,u.language),n.hooks.run("before-insert",u),u.element.innerHTML=u.highlightedCode,r&&r.call(t),n.hooks.run("after-highlight",u),n.hooks.run("complete",u)},highlight:function(e,t,r){var l=n.tokenize(e,t);return a.stringify(n.util.encode(l),r)},tokenize:function(e,t){var a=n.Token,r=[e],l=t.rest;if(l){for(var i in l)t[i]=l[i];delete t.rest}e:for(var i in t)if(t.hasOwnProperty(i)&&t[i]){var o=t[i];o="Array"===n.util.type(o)?o:[o];for(var s=0;s<o.length;++s){var u=o[s],c=u.inside,g=!!u.lookbehind,h=!!u.greedy,f=0,d=u.alias;u=u.pattern||u;for(var p=0;p<r.length;p++){var m=r[p];if(r.length>e.length)break e;if(!(m instanceof a)){u.lastIndex=0;var y=u.exec(m),v=1;if(!y&&h&&p!=r.length-1){var b=r[p+1].matchedStr||r[p+1],k=m+b;if(p<r.length-2&&(k+=r[p+2].matchedStr||r[p+2]),u.lastIndex=0,y=u.exec(k),!y)continue;var w=y.index+(g?y[1].length:0);if(w>=m.length)continue;var _=y.index+y[0].length,P=m.length+b.length;if(v=3,P>=_){if(r[p+1].greedy)continue;v=2,k=k.slice(0,P)}m=k}if(y){g&&(f=y[1].length);var w=y.index+f,y=y[0].slice(f),_=w+y.length,S=m.slice(0,w),O=m.slice(_),j=[p,v];S&&j.push(S);var A=new a(i,c?n.tokenize(y,c):y,d,y,h);j.push(A),O&&j.push(O),Array.prototype.splice.apply(r,j)}}}}}return r},hooks:{all:{},add:function(e,t){var a=n.hooks.all;a[e]=a[e]||[],a[e].push(t)},run:function(e,t){var a=n.hooks.all[e];if(a&&a.length)for(var r,l=0;r=a[l++];)r(t)}}},a=n.Token=function(e,t,n,a,r){this.type=e,this.content=t,this.alias=n,this.matchedStr=a||null,this.greedy=!!r};if(a.stringify=function(e,t,r){if("string"==typeof e)return e;if("Array"===n.util.type(e))return e.map(function(n){return a.stringify(n,t,e)}).join("");var l={type:e.type,content:a.stringify(e.content,t,r),tag:"span",classes:["token",e.type],attributes:{},language:t,parent:r};if("comment"==l.type&&(l.attributes.spellcheck="true"),e.alias){var i="Array"===n.util.type(e.alias)?e.alias:[e.alias];Array.prototype.push.apply(l.classes,i)}n.hooks.run("wrap",l);var o="";for(var s in l.attributes)o+=(o?" ":"")+s+'="'+(l.attributes[s]||"")+'"';return"<"+l.tag+' class="'+l.classes.join(" ")+'" '+o+">"+l.content+"</"+l.tag+">"},!_self.document)return _self.addEventListener?(_self.addEventListener("message",function(e){var t=JSON.parse(e.data),a=t.language,r=t.code,l=t.immediateClose;_self.postMessage(n.highlight(r,n.languages[a],a)),l&&_self.close()},!1),_self.Prism):_self.Prism;var r=document.currentScript||[].slice.call(document.getElementsByTagName("script")).pop();return r&&(n.filename=r.src,document.addEventListener&&!r.hasAttribute("data-manual")&&document.addEventListener("DOMContentLoaded",n.highlightAll)),_self.Prism}();"undefined"!=typeof module&&module.exports&&(module.exports=Prism),"undefined"!=typeof global&&(global.Prism=Prism);
</script>

<script type="text/javascript">
Prism.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\w\W]*?\*\//,lookbehind:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0}],string:{pattern:/(["'])(\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"class-name":{pattern:/((?:\b(?:class|interface|extends|implements|trait|instanceof|new)\s+)|(?:catch\s+\())[a-z0-9_\.\\]+/i,lookbehind:!0,inside:{punctuation:/(\.|\\)/}},keyword:/\b(if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/,"boolean":/\b(true|false)\b/,"function":/[a-z0-9_]+(?=\()/i,number:/\b-?(?:0x[\da-f]+|\d*\.?\d+(?:e[+-]?\d+)?)\b/i,operator:/--?|\+\+?|!=?=?|<=?|>=?|==?=?|&&?|\|\|?|\?|\*|\/|~|\^|%/,punctuation:/[{}[\];(),.:]/};
</script>

<script type="text/javascript">
Prism.languages.c=Prism.languages.extend("clike",{keyword:/\b(asm|typeof|inline|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|int|long|register|return|short|signed|sizeof|static|struct|switch|typedef|union|unsigned|void|volatile|while)\b/,operator:/\-[>-]?|\+\+?|!=?|<<?=?|>>?=?|==?|&&?|\|?\||[~^%?*\/]/,number:/\b-?(?:0x[\da-f]+|\d*\.?\d+(?:e[+-]?\d+)?)[ful]*\b/i}),Prism.languages.insertBefore("c","string",{macro:{pattern:/(^\s*)#\s*[a-z]+([^\r\n\\]|\\.|\\(?:\r\n?|\n))*/im,lookbehind:!0,alias:"property",inside:{string:{pattern:/(#\s*include\s*)(<.+?>|("|')(\\?.)+?\3)/,lookbehind:!0},directive:{pattern:/(#\s*)\b(define|elif|else|endif|error|ifdef|ifndef|if|import|include|line|pragma|undef|using)\b/,lookbehind:!0,alias:"keyword"}}},constant:/\b(__FILE__|__LINE__|__DATE__|__TIME__|__TIMESTAMP__|__func__|EOF|NULL|stdin|stdout|stderr)\b/}),delete Prism.languages.c["class-name"],delete Prism.languages.c["boolean"];
</script>

<script type="text/javascript">
Prism.languages.cpp=Prism.languages.extend("c",{keyword:/\b(alignas|alignof|asm|auto|bool|break|case|catch|char|char16_t|char32_t|class|compl|const|constexpr|const_cast|continue|decltype|default|delete|do|double|dynamic_cast|else|enum|explicit|export|extern|float|for|friend|goto|if|inline|int|long|mutable|namespace|new|noexcept|nullptr|operator|private|protected|public|register|reinterpret_cast|requires|return|short|signed|sizeof|static|static_assert|static_cast|struct|switch|template|this|thread_local|throw|try|typedef|typeid|typename|union|unsigned|using|virtual|void|volatile|wchar_t|while)\b/,"boolean":/\b(true|false)\b/,operator:/[-+]{1,2}|!=?|<{1,2}=?|>{1,2}=?|\->|:{1,2}|={1,2}|\^|~|%|&{1,2}|\|?\||\?|\*|\/|\b(and|and_eq|bitand|bitor|not|not_eq|or|or_eq|xor|xor_eq)\b/}),Prism.languages.insertBefore("cpp","keyword",{"class-name":{pattern:/(class\s+)[a-z0-9_]+/i,lookbehind:!0}});
</script>
</head>
<body>

<address align=right>
Document number: P0892R0 <br />
Date: 2017-12-11 <br />
Audience: Evolution Working Group <br />
Reply-To: Barry Revzin &lt;barry.revzin@gmail.com> <br />
Stephan T. Lavavej &lt;stl@exchange.microsoft.com>
</address>
<hr/>
<h1 align=center>explicit(bool)</h1>

<h2>Contents</h2>

<ul>
<li><a href="#Motivation">Motivation</a></li>
<li><a href="#Proposal">Proposal</a></li>
<li><a href="#Wording">Wording</a></li>
<li><a href="#Acks">Acknowledgements</a></li>
</ul>

<a name="Motivation"> </a><h2>Motivation</h2>

<p>When writing a class template which wraps a member of template parameter type, it's useful to expose constructors that allow the user to construct the member in place. In order to do this properly, fulfilling the usage that the class designer expects, such constructors need to be <code class="language-cpp">explicit</code> or not based on whether the corresponding class's constructor is <code class="language-cpp">explicit</code> or not. Conditionally explicit constructors appear throughout the standard library in some of the most commonly used utility types - <code class="language-cpp">std::pair</code>, <code class="language-cpp">std::tuple</code>, and now <code class="language-cpp">std::optional</code> and <code class="language-cpp">std::variant</code> too, among others. This permits very natural code:

<pre><code class="language-cpp">pair&lt;string, string> safe() {
    return {"meow", "purr"}; // ok
}

pair&lt;vector&lt;int>, vector&lt;int>> unsafe() {
    return {11, 22}; // error
}
</code></pre>

<p>Despite being very useful functionality, it is quite cumbersome to implement. While conceptually we talk about a constructor being "conditionally <code class="language-cpp">explicit</code>," the only way to implement that functionality is to write two constructors that are mutually disjoint - both of which beyond that do exactly the same thing. This gets a little better with concepts, where at least we don't have to duplicate the convertibility trait, but either way we have two duplicated constructors, and you just have to know why they're written the way they are. Here is an example from <code>std::pair</code>:

<table style="width:100%">
<tr><th style="width:50%">C++17 today (SFINAE)</th><th style="width:50%">With Concepts</th></tr>
<tr><td><pre style="background:transparent;border:0px"><code class="language-cpp">template &lt;typename T1, typename T2>
struct pair {
    template &lt;typename U1=T1, typename U2=T2,
        std::enable_if_t&lt;
            std::is_constructible_v&lt;T1, U1> &&
            std::is_constructible_v&lt;T2, U2> &&
            std::is_convertible_v&lt;U1, T1> &&
            std::is_convertible_v&lt;U2, T2>
        , int> = 0>
    constexpr pair(U1&&, U2&& );
    
    template &lt;typename U1=T1, typename U2=T2,
        std::enable_if_t&lt;
            std::is_constructible_v&lt;T1, U1> &&
            std::is_constructible_v&lt;T2, U2> &&
            !(std::is_convertible_v&lt;U1, T1> &&
              std::is_convertible_v&lt;U2, T2>)
        , int> = 0>
    explicit constexpr pair(U1&&, U2&& );    
};</code></pre></td>
<td><pre style="background:transparent;border:0px"><code class="language-cpp">template &lt;typename T1, typename T2>
struct pair {
    template &lt;typename U1=T1, typename U2=T2>
        requires std::is_constructible_v&lt;T1, U1> &&
            std::is_constructible_v&lt;T2, U2> &&
            std::is_convertible_v&lt;U1, T1> &&
            std::is_convertible_v&lt;U2, T2>
    constexpr pair(U1&&, U2&& );
    
    template &lt;typename U1=T1, typename U2=T2>
        requires std::is_constructible_v&lt;T1, U1> &&
            std::is_constructible_v&lt;T2, U2>
    explicit constexpr pair(U1&&, U2&& );    
};</code></pre></td></tr>
</table>

<p>These aren't conceptually two constructors and they aren't meaningfully two constructors. The intent of the design is to have one single, conditionally explicit constructor. While this trick works, it's a fairly tedious, verbose, repetitive solution. How many third party libraries have code that <i>should</i> follow this idiom but doesn't due to the difficulty? Let's do better.
    
<a name="Proposal"></a><h2>Proposal</h2>

<p>The proposal is simply to allow for the direct declaration of conditionally <code class="language-cpp">explicit</code> constructors (and conversion operators) in the same way that we currently specify that a function is conditionally <code class="language-cpp">noexcept</code>: with an extra boolean constant argument. That would allow the above example to be written much more directly as:

<table style="width:100%">
<tr><th style="width:50%">SFINAE</th><th style="width:50%">SFINAE + explicit(bool)</th></tr>
<tr><td><pre style="background:transparent;border:0px"><code class="language-cpp">template &lt;typename T1, typename T2>
struct pair {
    template &lt;typename U1=T1, typename U2=T2,
        std::enable_if_t&lt;
            std::is_constructible_v&lt;T1, U1> &&
            std::is_constructible_v&lt;T2, U2> &&
            std::is_convertible_v&lt;U1, T1> &&
            std::is_convertible_v&lt;U2, T2>
        , int> = 0>
    constexpr pair(U1&&, U2&& );
    
    template &lt;typename U1=T1, typename U2=T2,
        std::enable_if_t&lt;
            std::is_constructible_v&lt;T1, U1> &&
            std::is_constructible_v&lt;T2, U2> &&
            !(std::is_convertible_v&lt;U1, T1> &&
              std::is_convertible_v&lt;U2, T2>)
        , int> = 0>
    explicit constexpr pair(U1&&, U2&& );    
};</code></pre></td>
<td><pre style="background:transparent;border:0px"><code class="language-cpp">template &lt;typename T1, typename T2>
struct pair {
    template &lt;typename U1=T1, typename U2=T2,
        std::enable_if_t&lt;
            std::is_constructible_v&lt;T1, U1> &&
            std::is_constructible_v&lt;T2, U2>
        , int> = 0>
    explicit(!std::is_convertible_v&lt;U1, T1> ||
        !std::is_convertible_v&lt;U2, T2>)
    constexpr pair(U1&&, U2&& );   
};</code></pre></td></tr>
<tr><th style="width:50%">Concepts</th><th style="width:50%">Concepts + explicit(bool)</th></tr>
<tr><td><pre style="background:transparent;border:0px"><code class="language-cpp">template &lt;typename T1, typename T2>
struct pair {
    template &lt;typename U1=T1, typename U2=T2>
        requires std::is_constructible_v&lt;T1, U1> &&
            std::is_constructible_v&lt;T2, U2> &&
            std::is_convertible_v&lt;U1, T1> &&
            std::is_convertible_v&lt;U2, T2>
    constexpr pair(U1&&, U2&& );
    
    template &lt;typename U1=T1, typename U2=T2>
        requires std::is_constructible_v&lt;T1, U1> &&
            std::is_constructible_v&lt;T2, U2>
    explicit constexpr pair(U1&&, U2&& );    
};</code></pre></td>
<td><pre style="background:transparent;border:0px"><code class="language-cpp">template &lt;typename T1, typename T2>
struct pair {
    template &lt;typename U1=T1, typename U2=T2>
        requires std::is_constructible_v&lt;T1, U1> &&
            std::is_constructible_v&lt;T2, U2>
    explicit(!std::is_convertible_v&lt;U1, T1> ||
        !std::is_convertible_v&lt;U2, T2>)
    constexpr pair(U1&&, U2&& );
};</code></pre></td></tr>
</table>

<p>In both cases, the constructor at the right is <code class="language-cpp">explicit</code> if the condition in parentheses is <code class="language-cpp">true</code>, otherwise it's not. <i>One</i> truly, conditionally explicit constructor - finally a direct way to express our intent.

<p>This is a pure language extension, such syntax is ill-formed today, and no existing code will break.

<a name="Wording"></a><h2>Proposed Wording</h2>

<p>In 10.1.2 [dcl.fct.spec] paragraph 1:

<blockquote class="std"><i>Function-specifiers</i> can be used only in function declarations.
<div style="padding-left: 1em" /><i>function-specifier</i>:</div>
<div style="padding-left: 2em;"><code>virtual</code></div>
<div style="padding-left: 2em;"><del><code>explicit</code></del></div>
<div style="padding-left: 2em;"><ins><i>explicit-specifier</i></div>
<div style="padding-left: 1em" /><ins><i>explicit-specifier</i>:</ins></div>
<div style="padding-left: 2em;"><ins><code>explicit (</code><i>constant-expression</i><code>)</code></ins></div>
<div style="padding-left: 2em;"><ins><code>explicit</code></ins></div>
</blockquote>

In 10.1.2 [dcl.fct.spec] paragraph 3:

<blockquote class="std"><del>The <code>explicit</code> specifier</del><ins>An <i>explicit-specifier</i></ins> shall be used only in the declaration of a constructor or conversion function within its class definition [...]</blockquote>

Insert new paragraph after 10.1.2 [dcl.fct.spec] paragraph 3:

<blockquote class="std"><ins>In an <i>explicit-specifier</i>, the <i>constant-expression</i>, if supplied, shall be a contextually converted constant expression of type <code>bool</code>. If that constant expression is true, the function is explicit. Otherwise, the function is not explicit. A <code>(</code> token that follows <code>explicit</code> is part of the <i>explicit-specifier</i> and does not commence an initializer. The <i>explicit-specifier</i> <code>explicit</code> without a <i>constant-expression</i> is equivalent to the <i>explicit-specifier</i> <code>explicit(true)</code>.</ins></blockquote>

<p>In 11.3 [dcl.meaning], paragraph 2:

<blockquote class="std">A <code>static</code>, <code>thread_local</code>, <code>extern</code>, <code>mutable</code>, <code>friend</code>, <code>inline</code>, <code>virtual</code>, <code>constexpr</code>, <del><code>explicit</code>,</del> or <code>typedef</code> specifier <ins>or <i>explicit-specifier</i></ins> applies directly to each <i>declarator-id</i> in an <i>init-declarator-list</i> or <i>member-declarator-list</i>; [...]</blockquote>

<p> In 11.6.1 [dcl.init.aggr], paragraph 1, change explicit to not use code font:

<blockquote class="std">An <i>aggregate</i> is an array or a class with
<ul>
<li>no user-provided, <del><code>explicit</code></del> <ins>explicit</ins>, or inherited constructors (15.1 [class.ctor]),
<li>[...]
</ul></blockquote>

<p>In 15.1 [class.ctor], paragraph 1:

<blockquote class="std">In a constructor declaration, each <i>decl-specifier</i> in the optional <i>decl-specifier-seq</i> shall be <code>friend</code>, <code>inline</code>, <del><code>explicit</code>, or</del> <code>constexpr</code> <ins>, or an <i>explicit-specifier</i></ins>.</blockquote>

<p>In 15.3.1 [class.conv.ctor], paragraph 1:

<blockquote class="std">A constructor  <ins>that is not explicit (10.1.2 [dcl.fct.spec])</ins> <del>declared without the <i>function-specifier</i> <code>explicit</code></del> specifies a conversion from the types of its parameters (if any) to the type of its class. Such a constructor is called a <i>converting constructor</i>.</blockquote>

<p>In 16.3.1.7 [over.match.list], paragraph 1, change explicit to not use code font:

<blockquote class="std">If the initializer list has no elements and <code>T</code> has a default constructor, the first phase is omitted. In copy-list-initialization, if an <del><code>explicit</code></del> <ins>explicit</ins> constructor is chosen, the initialization is ill-formed.</blockquote>

<p>In 16.3.1.8 [over.match.class.deduct], paragraph 2, change explicit to not use code font:

<blockquote class="std">Each such notional constructor is considered to be explicit if the function or function template was generated from a constructor or <i>deduction-guide</i> that was declared <del><code>explicit</code></del> <ins>explicit</ins>.</blockquote>

<p>In 20.4.2.2 [functions.within.classes], the note is no longer necessary:

<blockquote class="std">For the sake of exposition, the library clauses sometimes annotate constructors with <code><i>EXPLICIT</i></code>. Such a constructor is conditionally declared as either explicit or non-explicit (15.3.1 [class.conv.ctor]). <del>[<i>Note</i>: This is typically implemented by declaring two such constructors, of which at most one participates in overload resolution. —<i>end note</i>]</del></blockquote>

<p>In 23.6.3.1 [optional.ctor], the note is no longer necessary:

<blockquote class="std"><del>[<i>Note</i>: The following constructors are conditionally specified as explicit. This is typically implemented by declaring two such constructors, of which at most one participates in overload resolution. —<i>end note</i>]</del>
<p><code>template&lt;class U = T> <i>EXPLICIT</i> constexpr optional(U&& v);</code>
</blockquote>

<a name="Acks"> </a><h2>Acknowledgements</h2>

Thanks to Titus Winters, whose EWG Wishlist thread led to the creation of this proposal. 

</body>
</html>