<!DOCTYPE html>

<html lang="en">

<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="apple-mobile-web-app-status-bar-style" content="black">
    <meta name="mobile-web-app-capable" content="yes">
    <title>
        Concept-defined placeholder types - HackMD
    </title>
    <link rel="icon" type="image/png" href="https://hackmd.io/favicon.png">
    <link rel="apple-touch-icon" href="https://hackmd.io/apple-touch-icon.png">

    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha256-916EbMg70RQy9LHiGkXzG8hSg9EdNy97GazNG/aiY1w=" crossorigin="anonymous" />
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" integrity="sha256-eZrrJcwDc/3uDhsdt61sL2oOBY362qM3lon1gyExkL0=" crossorigin="anonymous" />
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/ionicons/2.0.1/css/ionicons.min.css" integrity="sha256-3iu9jgsy9TpTwXKb7bNQzqWekRX7pPK+2OLj3R922fo=" crossorigin="anonymous" />
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/octicons/3.5.0/octicons.min.css" integrity="sha256-QiWfLIsCT02Sdwkogf6YMiQlj4NE84MKkzEMkZnMGdg=" crossorigin="anonymous" />
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.5.1/themes/prism.min.css" integrity="sha256-vtR0hSWRc3Tb26iuN2oZHt3KRUomwTufNIf5/4oeCyg=" crossorigin="anonymous" />
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/emojify.js/1.1.0/css/basic/emojify.min.css" integrity="sha256-UOrvMOsSDSrW6szVLe8ZDZezBxh5IoIfgTwdNDgTjiU=" crossorigin="anonymous" />
    <style>
        @import url(https://fonts.googleapis.com/css?family=Roboto:300,300i,400,400i,500,500i|Source+Code+Pro:300,400,500|Source+Sans+Pro:300,300i,400,400i,600,600i|Source+Serif+Pro&subset=latin-ext);.hljs{display:block;background:#fff;padding:.5em;color:#333;overflow-x:auto}.hljs-comment,.hljs-meta{color:#969896}.hljs-emphasis,.hljs-quote,.hljs-string,.hljs-strong,.hljs-template-variable,.hljs-variable{color:#df5000}.hljs-keyword,.hljs-selector-tag,.hljs-type{color:#a71d5d}.hljs-attribute,.hljs-bullet,.hljs-literal,.hljs-number,.hljs-symbol{color:#0086b3}.hljs-built_in,.hljs-builtin-name{color:#005cc5}.hljs-name,.hljs-section{color:#63a35c}.hljs-tag{color:#333}.hljs-attr,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-id,.hljs-selector-pseudo,.hljs-title{color:#795da3}.hljs-addition{color:#55a532;background-color:#eaffea}.hljs-deletion{color:#bd2c00;background-color:#ffecec}.hljs-link{text-decoration:underline}.markdown-body{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica,Arial,sans-serif;font-size:16px;line-height:1.5;word-wrap:break-word}.markdown-body:after,.markdown-body:before{display:table;content:""}.markdown-body:after{clear:both}.markdown-body>:first-child{margin-top:0!important}.markdown-body>:last-child{margin-bottom:0!important}.markdown-body a:not([href]){color:inherit;text-decoration:none}.markdown-body .absent{color:#c00}.markdown-body .anchor{float:left;padding-right:4px;margin-left:-20px;line-height:1}.markdown-body .anchor:focus{outline:none}.markdown-body blockquote,.markdown-body dl,.markdown-body ol,.markdown-body p,.markdown-body pre,.markdown-body table,.markdown-body ul{margin-top:0;margin-bottom:16px}.markdown-body hr{height:.25em;padding:0;margin:24px 0;background-color:#e7e7e7;border:0}.markdown-body blockquote{font-size:16px;padding:0 1em;color:#777;border-left:.25em solid #ddd}.markdown-body blockquote>:first-child{margin-top:0}.markdown-body blockquote>:last-child{margin-bottom:0}.markdown-body .loweralpha{list-style-type:lower-alpha}.markdown-body h1,.markdown-body h2,.markdown-body h3,.markdown-body h4,.markdown-body h5,.markdown-body h6{margin-top:24px;margin-bottom:16px;font-weight:600;line-height:1.25}.markdown-body h1 .octicon-link,.markdown-body h2 .octicon-link,.markdown-body h3 .octicon-link,.markdown-body h4 .octicon-link,.markdown-body h5 .octicon-link,.markdown-body h6 .octicon-link{color:#000;vertical-align:middle;visibility:hidden}.markdown-body h1:hover .anchor,.markdown-body h2:hover .anchor,.markdown-body h3:hover .anchor,.markdown-body h4:hover .anchor,.markdown-body h5:hover .anchor,.markdown-body h6:hover .anchor{text-decoration:none}.markdown-body h1:hover .anchor .octicon-link,.markdown-body h2:hover .anchor .octicon-link,.markdown-body h3:hover .anchor .octicon-link,.markdown-body h4:hover .anchor .octicon-link,.markdown-body h5:hover .anchor .octicon-link,.markdown-body h6:hover .anchor .octicon-link{visibility:visible}.markdown-body h1 code,.markdown-body h1 tt,.markdown-body h2 code,.markdown-body h2 tt,.markdown-body h3 code,.markdown-body h3 tt,.markdown-body h4 code,.markdown-body h4 tt,.markdown-body h5 code,.markdown-body h5 tt,.markdown-body h6 code,.markdown-body h6 tt{font-size:inherit}.markdown-body h1{font-size:2em}.markdown-body h1,.markdown-body h2{padding-bottom:.3em;border-bottom:1px solid #eee}.markdown-body h2{font-size:1.5em}.markdown-body h3{font-size:1.25em}.markdown-body h4{font-size:1em}.markdown-body h5{font-size:.875em}.markdown-body h6{font-size:.85em;color:#777}.markdown-body ol,.markdown-body ul{padding-left:2em}.markdown-body ol.no-list,.markdown-body ul.no-list{padding:0;list-style-type:none}.markdown-body ol ol,.markdown-body ol ul,.markdown-body ul ol,.markdown-body ul ul{margin-top:0;margin-bottom:0}.markdown-body li>p{margin-top:16px}.markdown-body li+li{margin-top:.25em}.markdown-body dl{padding:0}.markdown-body dl dt{padding:0;margin-top:16px;font-size:1em;font-style:italic;font-weight:700}.markdown-body dl dd{padding:0 16px;margin-bottom:16px}.markdown-body table{display:block;width:100%;overflow:auto;word-break:normal;word-break:keep-all}.markdown-body table th{font-weight:700}.markdown-body table td,.markdown-body table th{padding:6px 13px;border:1px solid #ddd}.markdown-body table tr{background-color:#fff;border-top:1px solid #ccc}.markdown-body table tr:nth-child(2n){background-color:#f8f8f8}.markdown-body img{max-width:100%;box-sizing:content-box;background-color:#fff}.markdown-body img[align=right]{padding-left:20px}.markdown-body img[align=left]{padding-right:20px}.markdown-body .emoji{max-width:none;vertical-align:text-top;background-color:transparent}.markdown-body span.frame{display:block;overflow:hidden}.markdown-body span.frame>span{display:block;float:left;width:auto;padding:7px;margin:13px 0 0;overflow:hidden;border:1px solid #ddd}.markdown-body span.frame span img{display:block;float:left}.markdown-body span.frame span span{display:block;padding:5px 0 0;clear:both;color:#333}.markdown-body span.align-center{display:block;overflow:hidden;clear:both}.markdown-body span.align-center>span{display:block;margin:13px auto 0;overflow:hidden;text-align:center}.markdown-body span.align-center span img{margin:0 auto;text-align:center}.markdown-body span.align-right{display:block;overflow:hidden;clear:both}.markdown-body span.align-right>span{display:block;margin:13px 0 0;overflow:hidden;text-align:right}.markdown-body span.align-right span img{margin:0;text-align:right}.markdown-body span.float-left{display:block;float:left;margin-right:13px;overflow:hidden}.markdown-body span.float-left span{margin:13px 0 0}.markdown-body span.float-right{display:block;float:right;margin-left:13px;overflow:hidden}.markdown-body span.float-right>span{display:block;margin:13px auto 0;overflow:hidden;text-align:right}.markdown-body code,.markdown-body tt{padding:0;padding-top:.2em;padding-bottom:.2em;margin:0;font-size:85%;background-color:rgba(0,0,0,.04);border-radius:3px}.markdown-body code:after,.markdown-body code:before,.markdown-body tt:after,.markdown-body tt:before{letter-spacing:-.2em;content:"\00a0"}.markdown-body code br,.markdown-body tt br{display:none}.markdown-body del code{text-decoration:inherit}.markdown-body pre{word-wrap:normal}.markdown-body pre>code{padding:0;margin:0;font-size:100%;word-break:normal;white-space:pre;background:transparent;border:0}.markdown-body .highlight{margin-bottom:16px}.markdown-body .highlight pre{margin-bottom:0;word-break:normal}.markdown-body .highlight pre,.markdown-body pre{padding:16px;overflow:auto;font-size:85%;line-height:1.45;background-color:#f7f7f7;border-radius:3px}.markdown-body pre code,.markdown-body pre tt{display:inline;max-width:auto;padding:0;margin:0;overflow:visible;line-height:inherit;word-wrap:normal;background-color:transparent;border:0}.markdown-body pre code:after,.markdown-body pre code:before,.markdown-body pre tt:after,.markdown-body pre tt:before{content:normal}.markdown-body .csv-data td,.markdown-body .csv-data th{padding:5px;overflow:hidden;font-size:12px;line-height:1;text-align:left;white-space:nowrap}.markdown-body .csv-data .blob-line-num{padding:10px 8px 9px;text-align:right;background:#fff;border:0}.markdown-body .csv-data tr{border-top:0}.markdown-body .csv-data th{font-weight:700;background:#f8f8f8;border-top:0}.markdown-body kbd{display:inline-block;padding:3px 5px;font-size:11px;line-height:10px;color:#555;vertical-align:middle;background-color:#fcfcfc;border:1px solid #ccc;border-bottom-color:#bbb;border-radius:3px;box-shadow:inset 0 -1px 0 #bbb}.news .alert .markdown-body blockquote{padding:0 0 0 40px;border:0 none}.activity-tab .news .alert .commits,.activity-tab .news .markdown-body blockquote{padding-left:0}.task-list-item{list-style-type:none}.task-list-item label{font-weight:400}.task-list-item.enabled label{cursor:pointer}.task-list-item+.task-list-item{margin-top:3px}.task-list-item-checkbox{float:left;margin:.31em 0 .2em -1.3em!important;vertical-align:middle;cursor:default!important}.markdown-body{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Helvetica,Arial,sans-serif;padding-top:40px;padding-bottom:40px;max-width:758px;overflow:visible!important}.markdown-body .emoji{vertical-align:top}.markdown-body pre{border:inherit!important}.markdown-body code{color:inherit!important}.markdown-body pre code .wrapper{display:-moz-inline-flex;display:-ms-inline-flex;display:-o-inline-flex;display:inline-flex}.markdown-body pre code .gutter{float:left;overflow:hidden;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.markdown-body pre code .gutter.linenumber{text-align:right;position:relative;display:inline-block;cursor:default;z-index:4;padding:0 8px 0 0;min-width:20px;box-sizing:content-box;color:#afafaf!important;border-right:3px solid #6ce26c!important}.markdown-body pre code .gutter.linenumber>span:before{content:attr(data-linenumber)}.markdown-body pre code .code{float:left;margin:0 0 0 16px}.markdown-body .gist .line-numbers{border-left:none;border-top:none;border-bottom:none}.markdown-body .gist .line-data{border:none}.markdown-body .gist table{border-spacing:0;border-collapse:inherit!important}.markdown-body code[data-gist-id]{background:none;padding:0}.markdown-body code[data-gist-id]:after,.markdown-body code[data-gist-id]:before{content:""}.markdown-body code[data-gist-id] .blob-num{border:unset}.markdown-body code[data-gist-id] table{overflow:unset;margin-bottom:unset}.markdown-body code[data-gist-id] table tr{background:unset}.markdown-body[dir=rtl] pre{direction:ltr}.markdown-body[dir=rtl] code{direction:ltr;unicode-bidi:embed}.markdown-body .alert>p{margin-bottom:0}.markdown-body pre.abc,.markdown-body pre.flow-chart,.markdown-body pre.graphviz,.markdown-body pre.mermaid,.markdown-body pre.sequence-diagram{text-align:center;background-color:inherit;border-radius:0;white-space:inherit}.markdown-body pre.abc>code,.markdown-body pre.flow-chart>code,.markdown-body pre.graphviz>code,.markdown-body pre.mermaid>code,.markdown-body pre.sequence-diagram>code{text-align:left}.markdown-body pre.abc>svg,.markdown-body pre.flow-chart>svg,.markdown-body pre.graphviz>svg,.markdown-body pre.mermaid>svg,.markdown-body pre.sequence-diagram>svg{max-width:100%;height:100%}.markdown-body pre>code.wrap{white-space:pre-wrap;white-space:-moz-pre-wrap;white-space:-pre-wrap;white-space:-o-pre-wrap;word-wrap:break-word}.markdown-body .alert>p,.markdown-body .alert>ul{margin-bottom:0}.markdown-body summary{display:list-item}.markdown-body summary:focus{outline:none}.markdown-body details summary{cursor:pointer}.markdown-body details:not([open])>:not(summary){display:none}.markdown-body figure{margin:1em 40px}.markdown-body .mark,.markdown-body mark{background-color:#fff1a7}.vimeo,.youtube{cursor:pointer;display:table;text-align:center;background-position:50%;background-repeat:no-repeat;background-size:contain;background-color:#000;overflow:hidden}.vimeo,.youtube{position:relative;width:100%}.youtube{padding-bottom:56.25%}.vimeo img{width:100%;-o-object-fit:contain;object-fit:contain;z-index:0}.youtube img{-o-object-fit:cover;object-fit:cover;z-index:0}.vimeo iframe,.youtube iframe,.youtube img{width:100%;height:100%;position:absolute;top:0;left:0}.vimeo iframe,.youtube iframe{vertical-align:middle;z-index:1}.vimeo .icon,.youtube .icon{position:absolute;height:auto;width:auto;top:50%;left:50%;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);color:#fff;opacity:.3;transition:opacity .2s;z-index:0}.vimeo:hover .icon,.youtube:hover .icon{opacity:.6;transition:opacity .2s}.slideshare .inner,.speakerdeck .inner{position:relative;width:100%}.slideshare .inner iframe,.speakerdeck .inner iframe{position:absolute;top:0;bottom:0;left:0;right:0;width:100%;height:100%}.MJX_Assistive_MathML{display:none}.ui-infobar{position:relative;z-index:2;max-width:758px;margin-top:25px;margin-bottom:-25px;color:#777}.ui-toc{position:fixed;bottom:20px;z-index:10000}.ui-toc-label{opacity:.3;background-color:#ccc;border:none;transition:opacity .2s}.ui-toc .open .ui-toc-label{opacity:1;color:#fff;transition:opacity .2s}.ui-toc-label:focus{opacity:.3;background-color:#ccc;color:#000}.ui-toc-label:hover{opacity:1;background-color:#ccc;transition:opacity .2s}.ui-toc-dropdown{margin-top:23px;margin-bottom:20px;padding-left:10px;padding-right:10px;max-width:45vw;width:25vw;max-height:70vh;overflow:auto;text-align:inherit}.ui-toc-dropdown>.toc{max-height:calc(70vh - 100px);overflow:auto}.ui-toc-dropdown[dir=rtl] .nav{padding-right:0;letter-spacing:.0029em}.ui-toc-dropdown a{overflow:hidden;text-overflow:ellipsis;white-space:pre}.ui-toc-dropdown .nav>li>a{display:block;padding:4px 20px;font-size:13px;font-weight:500;color:#767676}.ui-toc-dropdown .nav>li:first-child:last-child > ul,.ui-toc-dropdown .toc.expand ul{display:block}.ui-toc-dropdown .nav>li>a:focus,.ui-toc-dropdown .nav>li>a:hover{padding-left:19px;color:#000;text-decoration:none;background-color:transparent;border-left:1px solid #000}.ui-toc-dropdown[dir=rtl] .nav>li>a:focus,.ui-toc-dropdown[dir=rtl] .nav>li>a:hover{padding-right:19px;border-left:none;border-right:1px solid #000}.ui-toc-dropdown .nav>.active:focus>a,.ui-toc-dropdown .nav>.active:hover>a,.ui-toc-dropdown .nav>.active>a{padding-left:18px;font-weight:700;color:#000;background-color:transparent;border-left:2px solid #000}.ui-toc-dropdown[dir=rtl] .nav>.active:focus>a,.ui-toc-dropdown[dir=rtl] .nav>.active:hover>a,.ui-toc-dropdown[dir=rtl] .nav>.active>a{padding-right:18px;border-left:none;border-right:2px solid #000}.ui-toc-dropdown .nav .nav{display:none;padding-bottom:10px}.ui-toc-dropdown .nav>.active>ul{display:block}.ui-toc-dropdown .nav .nav>li>a{padding-top:1px;padding-bottom:1px;padding-left:30px;font-size:12px;font-weight:400}.ui-toc-dropdown[dir=rtl] .nav .nav>li>a{padding-right:30px}.ui-toc-dropdown .nav .nav>li>ul>li>a{padding-top:1px;padding-bottom:1px;padding-left:40px;font-size:12px;font-weight:400}.ui-toc-dropdown[dir=rtl] .nav .nav>li>ul>li>a{padding-right:40px}.ui-toc-dropdown .nav .nav>li>a:focus,.ui-toc-dropdown .nav .nav>li>a:hover{padding-left:29px}.ui-toc-dropdown[dir=rtl] .nav .nav>li>a:focus,.ui-toc-dropdown[dir=rtl] .nav .nav>li>a:hover{padding-right:29px}.ui-toc-dropdown .nav .nav>li>ul>li>a:focus,.ui-toc-dropdown .nav .nav>li>ul>li>a:hover{padding-left:39px}.ui-toc-dropdown[dir=rtl] .nav .nav>li>ul>li>a:focus,.ui-toc-dropdown[dir=rtl] .nav .nav>li>ul>li>a:hover{padding-right:39px}.ui-toc-dropdown .nav .nav>.active:focus>a,.ui-toc-dropdown .nav .nav>.active:hover>a,.ui-toc-dropdown .nav .nav>.active>a{padding-left:28px;font-weight:500}.ui-toc-dropdown[dir=rtl] .nav .nav>.active:focus>a,.ui-toc-dropdown[dir=rtl] .nav .nav>.active:hover>a,.ui-toc-dropdown[dir=rtl] .nav .nav>.active>a{padding-right:28px}.ui-toc-dropdown .nav .nav>.active>.nav>.active:focus>a,.ui-toc-dropdown .nav .nav>.active>.nav>.active:hover>a,.ui-toc-dropdown .nav .nav>.active>.nav>.active>a{padding-left:38px;font-weight:500}.ui-toc-dropdown[dir=rtl] .nav .nav>.active>.nav>.active:focus>a,.ui-toc-dropdown[dir=rtl] .nav .nav>.active>.nav>.active:hover>a,.ui-toc-dropdown[dir=rtl] .nav .nav>.active>.nav>.active>a{padding-right:38px}.markdown-body[lang^=ja]{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Helvetica,Arial,Hiragino Kaku Gothic Pro,ヒラギノ角ゴ Pro W3,Osaka,Meiryo,メイリオ,MS Gothic,ＭＳ\ ゴシック,sans-serif}.ui-toc-dropdown[lang^=ja]{font-family:Source Sans Pro,Helvetica,Arial,Meiryo UI,MS PGothic,ＭＳ\ Ｐゴシック,sans-serif}.markdown-body[lang=zh-tw]{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Helvetica,Arial,PingFang TC,Microsoft JhengHei,微軟正黑,sans-serif}.ui-toc-dropdown[lang=zh-tw]{font-family:Source Sans Pro,Helvetica,Arial,Microsoft JhengHei UI,微軟正黑UI,sans-serif}.markdown-body[lang=zh-cn]{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Helvetica,Arial,PingFang SC,Microsoft YaHei,微软雅黑,sans-serif}.ui-toc-dropdown[lang=zh-cn]{font-family:Source Sans Pro,Helvetica,Arial,Microsoft YaHei UI,微软雅黑UI,sans-serif}.ui-affix-toc{position:fixed;top:0;max-width:15vw;max-height:70vh;overflow:auto}.back-to-top,.expand-toggle,.go-to-bottom{display:block;padding:4px 10px;margin-top:10px;margin-left:10px;font-size:12px;font-weight:500;color:#999}.back-to-top:focus,.back-to-top:hover,.expand-toggle:focus,.expand-toggle:hover,.go-to-bottom:focus,.go-to-bottom:hover{color:#563d7c;text-decoration:none}.back-to-top,.go-to-bottom{margin-top:0}.ui-user-icon{width:20px;height:20px;display:block;border-radius:3px;margin-top:2px;margin-bottom:2px;margin-right:5px;background-position:50%;background-repeat:no-repeat;background-size:contain}.ui-user-icon.small{width:18px;height:18px;display:inline-block;vertical-align:middle;margin:0 0 .2em}.ui-infobar>small>span{line-height:22px}.ui-infobar>small .dropdown{display:inline-block}.ui-infobar>small .dropdown a:focus,.ui-infobar>small .dropdown a:hover{text-decoration:none}.unselectable{-moz-user-select:none;-webkit-user-select:none;-o-user-select:none;-ms-user-select:none;user-select:none}@media print{blockquote,div,img,pre,table{page-break-inside:avoid!important}a[href]:after{font-size:12px!important}}.markdown-body.slides{position:relative;z-index:1;color:#222}.markdown-body.slides:before{content:"";display:block;position:absolute;top:0;left:0;right:0;bottom:0;z-index:-1;background-color:currentColor;box-shadow:0 0 0 50vw}.markdown-body.slides section[data-markdown]{position:relative;margin-bottom:1.5em;background-color:#fff;text-align:center}.markdown-body.slides section[data-markdown] code{text-align:left}.markdown-body.slides section[data-markdown]:before{content:"";display:block;padding-bottom:56.23%}.markdown-body.slides section[data-markdown]>div:first-child{position:absolute;top:50%;left:1em;right:1em;-webkit-transform:translateY(-50%);transform:translateY(-50%);max-height:100%;overflow:hidden}.markdown-body.slides section[data-markdown]>ul{display:inline-block}.markdown-body.slides>section>section+section:after{content:"";position:absolute;top:-1.5em;right:1em;height:1.5em;border:3px solid #777}body{font-smoothing:subpixel-antialiased!important;-webkit-font-smoothing:subpixel-antialiased!important;-moz-osx-font-smoothing:auto!important;text-shadow:0 0 1em transparent,1px 1px 1.2px rgba(0,0,0,.004);-webkit-overflow-scrolling:touch;font-family:Source Sans Pro,Helvetica,Arial,sans-serif;letter-spacing:.025em}.focus,:focus{outline:none!important}::-moz-focus-inner{border:0!important}body.modal-open{overflow-y:auto;padding-right:0!important}
    </style>
    <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
    <!--[if lt IE 9]>
    	<script src="https://cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv.min.js" integrity="sha256-3Jy/GbSLrg0o9y5Z5n1uw0qxZECH7C6OQpVBgNFYa0g=" crossorigin="anonymous"></script>
    	<script src="https://cdnjs.cloudflare.com/ajax/libs/respond.js/1.4.2/respond.min.js" integrity="sha256-g6iAfvZp+nDQ2TdTR/VVKJf3bGro4ub5fvWSWVRi2NE=" crossorigin="anonymous"></script>
		<script src="https://cdnjs.cloudflare.com/ajax/libs/es5-shim/4.5.9/es5-shim.min.js" integrity="sha256-8E4Is26QH0bD52WoQpcB+R/tcWQtpzlCojrybUd7Mxo=" crossorigin="anonymous"></script>
    <![endif]-->
</head>

<body>
    <div id="doc" class="markdown-body container-fluid"><style>
ins { color: #080 }
s { color: #F00 }
blockquote.part { color: inherit !important }
tbody code { background-color: inherit !important }
</style><table><tbody>
<tr><th>Doc. no.:</th>    <td>P1158R0</td></tr>
<tr><th>Date:</th>    <td>2018-07-11</td></tr>
<tr><th>Audience:</th>    <td>EWG</td></tr>
<tr><th>Reply-to:</th>    <td>Zhihao Yuan &lt;zy at miator dot net&gt;</td></tr>
</tbody></table><h1 id="Concept-defined-placeholder-types" style=""><a class="anchor hidden-xs" href="#Concept-defined-placeholder-types" title="Concept-defined-placeholder-types"><span class="octicon octicon-link"></span></a>Concept-defined placeholder types</h1><pre><code class="c++ hljs"><span class="hljs-attribute">BidirectionalIterator</span> T;
<span class="hljs-attribute">T</span> it = foo();
</code></pre><h2 id="Motivation" style=""><a class="anchor hidden-xs" href="#Motivation" title="Motivation"><span class="octicon octicon-link"></span></a>Motivation</h2><p>We have three kinds of placeholder types to define variables – <code>auto</code>, <code>decltype(auto)</code>, and <code>ClassTemplate</code>.  The former two deduce arbitrary types, and the last one deduces specializations.  So that we can constrain the deduced type to be a pointer type with <code>auto*</code>, or we can constrain the deduced type to be a specialization of <code>std::iterator</code>, but we are not able to constrain the deduced type to be an <code>Iterator</code>.  We need the functionality to deduce types that satisfy the constraints expressed with Concepts.</p><h2 id="Introduction" style=""><a class="anchor hidden-xs" href="#Introduction" title="Introduction"><span class="octicon octicon-link"></span></a>Introduction</h2><p>The following example from P0915R0<sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup> shows a real issue when missing such a kind of constraints when declaring variables in generic code:</p><pre><code class="c++ hljs"><span class="hljs-keyword">template</span> &lt;<span class="hljs-keyword">typename</span> Producer&gt;
<span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">uploadToGPU</span><span class="hljs-params">(Producer&amp; producer)</span>
</span>{
    <span class="hljs-keyword">auto</span> item = producer.next();
    gpuMemcpy(dst, &amp;item, <span class="hljs-keyword">sizeof</span>(item));  <span class="hljs-comment">// potentially UB</span>
}
</code></pre><p>A quick and dirty fix is to use <code>static_assert</code>:</p><pre><code class="c++ hljs"><span class="hljs-keyword">template</span> &lt;<span class="hljs-keyword">typename</span> Producer&gt;
<span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">uploadToGPU</span><span class="hljs-params">(Producer&amp; producer)</span>
</span>{
    <span class="hljs-keyword">auto</span> item = producer.next();
    <span class="hljs-keyword">static_assert</span>(StandardLayoutType&lt;<span class="hljs-keyword">decltype</span>(item)&gt;);
    gpuMemcpy(dst, &amp;item, <span class="hljs-keyword">sizeof</span>(item));
}
</code></pre><p>which comes with a considerable distance between our idea and the code we written.  Here is a different workaround:</p><pre><code class="c++ hljs"><span class="hljs-keyword">template</span> &lt;<span class="hljs-keyword">typename</span> Producer&gt;
<span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">uploadToGPU</span><span class="hljs-params">(Producer&amp; producer)</span>
</span>{
    <span class="hljs-keyword">auto</span> item = producer.next();
    StandardLayoutObject(item);
    gpuMemcpy(dst, &amp;item, <span class="hljs-keyword">sizeof</span>(item));
}

<span class="hljs-keyword">template</span> &lt;StandardLayoutType T&gt;
<span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">StandardLayoutObject</span><span class="hljs-params">(T)</span> </span>{};
</code></pre><p>which is getting close.  Look at this <code>T</code>, it is</p><ul>
<li>used in place of a type for deduction,</li>
<li>constrained.</li>
</ul><p>It has all the functionalities we are <a href="#Motivation">motivated</a> to add.  The only issue is that it is a <em>constrained-parameter</em>, declared only in <em>template-parameter-list</em>.  Can we introduce such a <code>T</code> in other places?</p><pre><code class="c++ hljs"><span class="hljs-keyword">template</span> &lt;<span class="hljs-keyword">typename</span> Producer&gt;
<span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">uploadToGPU</span><span class="hljs-params">(Producer&amp; producer)</span>
</span>{
    StandardLayoutType T;
    T item = producer.next();
    gpuMemcpy(dst, &amp;item, <span class="hljs-keyword">sizeof</span>(item));
}
</code></pre><p>That is the feature we propose – a <em>constrained-type-name</em>.</p><h2 id="Design-Decisions" style=""><a class="anchor hidden-xs" href="#Design-Decisions" title="Design-Decisions"><span class="octicon octicon-link"></span></a>Design Decisions</h2><p>Model everything after <em>constrained-parameter</em>.</p><ol>
<li>In a <em>constrained-type-name</em>’s scope, the <em>constrained-type-name</em> can get involved in deduction multiple times, and must deduce to the same type.</li>
</ol><pre><code class="c++ hljs"><span class="hljs-keyword">template</span> &lt;Iterator T&gt;
<span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">foo</span><span class="hljs-params">(T, <span class="hljs-built_in">std</span>::move_iterator&lt;T&gt;)</span></span>;

Iterator T;
T it = begin(x);
<span class="hljs-comment">// ...</span>
<span class="hljs-built_in">std</span>::move_iterator&lt;T&gt; i2 = ...;
</code></pre><p>An rvalue reference to <em>constrained-type-name</em> is not a forwarding reference, because in</p><pre><code class="c++ hljs"><span class="hljs-keyword">template</span> &lt;Copyable T&gt;
<span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">foo</span><span class="hljs-params">(T&amp;&amp;)</span></span>;
</code></pre><p>The <code>foo</code> is invented rather than intended.  Class template argument deduction can model this intention better:</p><pre><code class="c++ hljs">Copyable T;
T &amp;&amp;a = <span class="hljs-string">'a'</span>;

<span class="hljs-keyword">template</span> &lt;Copyable T&gt;
<span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">Foo</span>
{</span>
    Foo(T&amp;&amp;);
};

Foo(<span class="hljs-string">'a'</span>)
</code></pre><p>A <em>constrained-type-name</em> is not deduced from a discarded statement in a template entity.</p><pre><code class="c++ hljs"><span class="hljs-keyword">template</span> &lt;<span class="hljs-keyword">auto</span>&gt;
<span class="hljs-function"><span class="hljs-keyword">auto</span> <span class="hljs-title">foo</span><span class="hljs-params">()</span>
</span>{ 
    Copyable T;
    <span class="hljs-function"><span class="hljs-keyword">if</span> <span class="hljs-title">constexpr</span> <span class="hljs-params">(cond)</span>
        T v </span>= ...;
    <span class="hljs-keyword">else</span>
        T u = ...;
    <span class="hljs-built_in">std</span>::<span class="hljs-keyword">aligned_storage_t</span>&lt;<span class="hljs-keyword">sizeof</span>(T), <span class="hljs-keyword">alignof</span>(T)&gt; s;
    ...
}
</code></pre><p>In the code above, <code>T</code> is only deduced from the <em>true</em> branch.</p><ol start="2">
<li>A <em>constrained-type-name</em> is a concrete type in non-deduced context after it has been deduced; if not deduced, the program is ill-formed.</li>
</ol><pre><code class="c++ hljs">template &lt;Copyable T&gt;
<span class="hljs-keyword">void</span> foo(std::array&lt;<span class="hljs-keyword">char</span>, <span class="hljs-keyword">sizeof</span>(T)&gt; a);

foo({ <span class="hljs-string">'a'</span>, <span class="hljs-string">'b'</span> });  <span class="hljs-comment">// ill-formed</span>

Copyable T;
std::array&lt;<span class="hljs-keyword">char</span>, <span class="hljs-keyword">sizeof</span>(T)&gt; a;  <span class="hljs-comment">// ill-formed</span>
</code></pre><p>A <em>constrained-type-name</em> is not deduced from a local class scope that is nested to the scope where the <em>constrained-type-name</em> is declared.</p><pre><code class="c++ hljs">Copyable T;
<span class="hljs-keyword">auto</span> f = [](<span class="hljs-keyword">char</span>* p, <span class="hljs-keyword">size_t</span> sz)
{
    T x = foo(p, sz);  <span class="hljs-comment">// ill-formed if T is not deduced elsewhere</span>
};
</code></pre><ol start="3">
<li>Deducing a <em>constrained-type-name</em> must use the copy-initialization syntax.  The code that involves <em>constrained-type-name</em> cannot be visually distinguished from initializations using concrete types, but we can limit the points of deduction by enforcing an <code>=</code> in front of the <em>initializer-clause</em>.  Meanwhile, it simplifies the semantics because the function parameters are also copy-initialized when deducing the function template parameters.</li>
</ol><pre><code class="c++ hljs"><span class="hljs-keyword">template</span> &lt;Iterator T&gt;
<span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">foo</span><span class="hljs-params">(T)</span></span>;

<span class="hljs-keyword">char</span> s[] = <span class="hljs-string">""</span>;
foo(s);

Iterator T;
T p = s;
<span class="hljs-function">T <span class="hljs-title">np</span><span class="hljs-params">(<span class="hljs-literal">nullptr</span>)</span></span>;    <span class="hljs-comment">// initializing char*</span>
foo(T(<span class="hljs-literal">nullptr</span>));  <span class="hljs-comment">// ok</span>
T ep = <span class="hljs-literal">nullptr</span>;   <span class="hljs-comment">// ill-formed, T has been deduced</span>
</code></pre><ol start="4">
<li>A <em>constrained-type-name</em> should only appear in block scope and have no linkage.  In class scopes, there is a complete analysis<sup class="footnote-ref"><a href="#fn2" id="fnref2">[2]</a></sup> to show why we will not have placeholder types on class members.  In namespace scopes, <em>constrained-type-name</em> itself will have ODR issues as soon as it gains linkage.</li>
</ol><h2 id="Technical-Description" style=""><a class="anchor hidden-xs" href="#Technical-Description" title="Technical-Description"><span class="octicon octicon-link"></span></a>Technical Description</h2><blockquote>
<p><em>simple-type-specifier</em>:<br>
&nbsp;&nbsp;&nbsp;&nbsp;[…]<br>
&nbsp;&nbsp;&nbsp;&nbsp;<code>auto</code><br>
&nbsp;&nbsp;&nbsp;&nbsp;<em>decltype-specifier</em><br>
&nbsp;&nbsp;&nbsp;&nbsp;<ins><em>constrained-type-name</em></ins><br></p>
<p><ins><em>constrained-type-name</em>:</ins><br>
&nbsp;&nbsp;&nbsp;&nbsp;<ins><em>identifier</em></ins></p>
</blockquote><blockquote>
<p><em>declaration</em>:<br>
&nbsp;&nbsp;&nbsp;&nbsp;[…]<br>
&nbsp;&nbsp;&nbsp;&nbsp;<em>attribute-declaration</em><br>
&nbsp;&nbsp;&nbsp;&nbsp;<ins><em>constrained-type-declaration</em></ins><br></p>
<p><ins><em>constrained-type-declaration</em>:</ins><br>
&nbsp;&nbsp;&nbsp;&nbsp;<ins><em>constrained-type-declarator-list</em> <code>;</code></ins><br></p>
<p><ins><em>constrained-type-declarator-list</em>:</ins><br>
&nbsp;&nbsp;&nbsp;&nbsp;<ins><em>constrained-type-declarator</em></ins><br>
&nbsp;&nbsp;&nbsp;&nbsp;<ins><em>constrained-type-declarator-list</em> <code>,</code> <em>constrained-type-declarator</em></ins><br></p>
<p><ins><em>constrained-type-declarator</em>:</ins><br>
&nbsp;&nbsp;&nbsp;&nbsp;<ins><em>qualified-concept-name</em> <em>identifier</em></ins><br></p>
<p>A <em>constrained-type-declaration</em> declares each <em>identifier</em> that a <em>constrained-type-declarator</em> ends with to be a <em>constrained-type-name</em>.  A <em>constrained-type-declaration</em> shall only appears at block scope.</p>
<p>A <em>constrained-type-name</em> is looked up as a <em>type-name</em> in its scope.  In an initializing declaration of a variable, Let <span class="mathjax"><span class="MathJax_Preview" style="color: inherit; display: none;"></span><span class="MathJax" id="MathJax-Element-1-Frame" tabindex="0" style="position: relative;" data-mathml="<math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;><mi>D</mi></math>" role="presentation"><nobr aria-hidden="true"><span class="math" id="MathJax-Span-1" style="width: 0.973em; display: inline-block;"><span style="display: inline-block; position: relative; width: 0.808em; height: 0px; font-size: 116%;"><span style="position: absolute; clip: rect(1.634em, 1000.78em, 2.64em, -1000em); top: -2.478em; left: 0em;"><span class="mrow" id="MathJax-Span-2"><span class="mi" id="MathJax-Span-3" style="font-family: MathJax_Math; font-style: italic;">D</span></span><span style="display: inline-block; width: 0px; height: 2.478em;"></span></span></span><span style="display: inline-block; overflow: hidden; vertical-align: -0.063em; border-left: 0px solid; width: 0px; height: 0.917em;"></span></span></nobr><span class="MJX_Assistive_MathML" role="presentation"><math xmlns="http://www.w3.org/1998/Math/MathML"><mi>D</mi></math></span></span><script type="math/tex" id="MathJax-Element-1">D</script></span> be a sequence of the <em>decl-specifiers</em> that are <em>type-specifiers</em> in the <em>decl-specifier-seq</em>.  If <span class="mathjax"><span class="MathJax_Preview" style="color: inherit; display: none;"></span><span class="MathJax" id="MathJax-Element-2-Frame" tabindex="0" style="position: relative;" data-mathml="<math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;><mi>D</mi></math>" role="presentation"><nobr aria-hidden="true"><span class="math" id="MathJax-Span-4" style="width: 0.973em; display: inline-block;"><span style="display: inline-block; position: relative; width: 0.808em; height: 0px; font-size: 116%;"><span style="position: absolute; clip: rect(1.634em, 1000.78em, 2.64em, -1000em); top: -2.478em; left: 0em;"><span class="mrow" id="MathJax-Span-5"><span class="mi" id="MathJax-Span-6" style="font-family: MathJax_Math; font-style: italic;">D</span></span><span style="display: inline-block; width: 0px; height: 2.478em;"></span></span></span><span style="display: inline-block; overflow: hidden; vertical-align: -0.063em; border-left: 0px solid; width: 0px; height: 0.917em;"></span></span></nobr><span class="MJX_Assistive_MathML" role="presentation"><math xmlns="http://www.w3.org/1998/Math/MathML"><mi>D</mi></math></span></span><script type="math/tex" id="MathJax-Element-2">D</script></span> mentions a <em>constrained-type-name</em> defined in the same scope and <span class="mathjax"><span class="MathJax_Preview" style="color: inherit; display: none;"></span><span class="MathJax" id="MathJax-Element-3-Frame" tabindex="0" style="position: relative;" data-mathml="<math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;><mi>D</mi></math>" role="presentation"><nobr aria-hidden="true"><span class="math" id="MathJax-Span-7" style="width: 0.973em; display: inline-block;"><span style="display: inline-block; position: relative; width: 0.808em; height: 0px; font-size: 116%;"><span style="position: absolute; clip: rect(1.634em, 1000.78em, 2.64em, -1000em); top: -2.478em; left: 0em;"><span class="mrow" id="MathJax-Span-8"><span class="mi" id="MathJax-Span-9" style="font-family: MathJax_Math; font-style: italic;">D</span></span><span style="display: inline-block; width: 0px; height: 2.478em;"></span></span></span><span style="display: inline-block; overflow: hidden; vertical-align: -0.063em; border-left: 0px solid; width: 0px; height: 0.917em;"></span></span></nobr><span class="MJX_Assistive_MathML" role="presentation"><math xmlns="http://www.w3.org/1998/Math/MathML"><mi>D</mi></math></span></span><script type="math/tex" id="MathJax-Element-3">D</script></span> followed by the <em>declarator</em> can form a function template argument in deduced context, this is a <em>constrained initializing declaration</em>, and after each <em>declarator</em> there shall be an <em>initializer-clause</em> followed by <code>=</code>.  Let <span class="mathjax"><span class="MathJax_Preview" style="color: inherit; display: none;"></span><span class="MathJax" id="MathJax-Element-4-Frame" tabindex="0" style="position: relative;" data-mathml="<math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;><msub><mi>I</mi><mn>1</mn></msub></math>" role="presentation"><nobr aria-hidden="true"><span class="math" id="MathJax-Span-10" style="width: 1.026em; display: inline-block;"><span style="display: inline-block; position: relative; width: 0.862em; height: 0px; font-size: 116%;"><span style="position: absolute; clip: rect(1.58em, 1000.86em, 2.736em, -1000em); top: -2.425em; left: 0em;"><span class="mrow" id="MathJax-Span-11"><span class="msubsup" id="MathJax-Span-12"><span style="display: inline-block; position: relative; width: 0.869em; height: 0px;"><span style="position: absolute; clip: rect(3.142em, 1000.5em, 4.149em, -1000em); top: -3.987em; left: 0em;"><span class="mi" id="MathJax-Span-13" style="font-family: MathJax_Math; font-style: italic;">I<span style="display: inline-block; overflow: hidden; height: 1px; width: 0.064em;"></span></span><span style="display: inline-block; width: 0px; height: 3.987em;"></span></span><span style="position: absolute; top: -3.837em; left: 0.44em;"><span class="mn" id="MathJax-Span-14" style="font-size: 70.7%; font-family: MathJax_Main;">1</span><span style="display: inline-block; width: 0px; height: 3.987em;"></span></span></span></span></span><span style="display: inline-block; width: 0px; height: 2.425em;"></span></span></span><span style="display: inline-block; overflow: hidden; vertical-align: -0.236em; border-left: 0px solid; width: 0px; height: 1.091em;"></span></span></nobr><span class="MJX_Assistive_MathML" role="presentation"><math xmlns="http://www.w3.org/1998/Math/MathML"><msub><mi>I</mi><mn>1</mn></msub></math></span></span><script type="math/tex" id="MathJax-Element-4">I_1</script></span>, <span class="mathjax"><span class="MathJax_Preview" style="color: inherit; display: none;"></span><span class="MathJax" id="MathJax-Element-5-Frame" tabindex="0" style="position: relative;" data-mathml="<math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;><msub><mi>I</mi><mn>2</mn></msub></math>" role="presentation"><nobr aria-hidden="true"><span class="math" id="MathJax-Span-15" style="width: 1.026em; display: inline-block;"><span style="display: inline-block; position: relative; width: 0.862em; height: 0px; font-size: 116%;"><span style="position: absolute; clip: rect(1.58em, 1000.86em, 2.736em, -1000em); top: -2.425em; left: 0em;"><span class="mrow" id="MathJax-Span-16"><span class="msubsup" id="MathJax-Span-17"><span style="display: inline-block; position: relative; width: 0.869em; height: 0px;"><span style="position: absolute; clip: rect(3.142em, 1000.5em, 4.149em, -1000em); top: -3.987em; left: 0em;"><span class="mi" id="MathJax-Span-18" style="font-family: MathJax_Math; font-style: italic;">I<span style="display: inline-block; overflow: hidden; height: 1px; width: 0.064em;"></span></span><span style="display: inline-block; width: 0px; height: 3.987em;"></span></span><span style="position: absolute; top: -3.837em; left: 0.44em;"><span class="mn" id="MathJax-Span-19" style="font-size: 70.7%; font-family: MathJax_Main;">2</span><span style="display: inline-block; width: 0px; height: 3.987em;"></span></span></span></span></span><span style="display: inline-block; width: 0px; height: 2.425em;"></span></span></span><span style="display: inline-block; overflow: hidden; vertical-align: -0.236em; border-left: 0px solid; width: 0px; height: 1.091em;"></span></span></nobr><span class="MJX_Assistive_MathML" role="presentation"><math xmlns="http://www.w3.org/1998/Math/MathML"><msub><mi>I</mi><mn>2</mn></msub></math></span></span><script type="math/tex" id="MathJax-Element-5">I_2</script></span>, …, <span class="mathjax"><span class="MathJax_Preview" style="color: inherit; display: none;"></span><span class="MathJax" id="MathJax-Element-6-Frame" tabindex="0" style="position: relative;" data-mathml="<math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;><msub><mi>I</mi><mi>n</mi></msub></math>" role="presentation"><nobr aria-hidden="true"><span class="math" id="MathJax-Span-20" style="width: 1.08em; display: inline-block;"><span style="display: inline-block; position: relative; width: 0.916em; height: 0px; font-size: 116%;"><span style="position: absolute; clip: rect(1.58em, 1000.92em, 2.744em, -1000em); top: -2.425em; left: 0em;"><span class="mrow" id="MathJax-Span-21"><span class="msubsup" id="MathJax-Span-22"><span style="display: inline-block; position: relative; width: 0.939em; height: 0px;"><span style="position: absolute; clip: rect(3.142em, 1000.5em, 4.149em, -1000em); top: -3.987em; left: 0em;"><span class="mi" id="MathJax-Span-23" style="font-family: MathJax_Math; font-style: italic;">I<span style="display: inline-block; overflow: hidden; height: 1px; width: 0.064em;"></span></span><span style="display: inline-block; width: 0px; height: 3.987em;"></span></span><span style="position: absolute; top: -3.837em; left: 0.44em;"><span class="mi" id="MathJax-Span-24" style="font-size: 70.7%; font-family: MathJax_Math; font-style: italic;">n</span><span style="display: inline-block; width: 0px; height: 3.987em;"></span></span></span></span></span><span style="display: inline-block; width: 0px; height: 2.425em;"></span></span></span><span style="display: inline-block; overflow: hidden; vertical-align: -0.246em; border-left: 0px solid; width: 0px; height: 1.1em;"></span></span></nobr><span class="MJX_Assistive_MathML" role="presentation"><math xmlns="http://www.w3.org/1998/Math/MathML"><msub><mi>I</mi><mi>n</mi></msub></math></span></span><script type="math/tex" id="MathJax-Element-6">I_n</script></span> be the list of <em>declarators</em>, <span class="mathjax"><span class="MathJax_Preview" style="color: inherit; display: none;"></span><span class="MathJax" id="MathJax-Element-7-Frame" tabindex="0" style="position: relative;" data-mathml="<math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;><msub><mi>E</mi><mn>1</mn></msub></math>" role="presentation"><nobr aria-hidden="true"><span class="math" id="MathJax-Span-25" style="width: 1.404em; display: inline-block;"><span style="display: inline-block; position: relative; width: 1.185em; height: 0px; font-size: 116%;"><span style="position: absolute; clip: rect(1.583em, 1001.18em, 2.736em, -1000em); top: -2.425em; left: 0em;"><span class="mrow" id="MathJax-Span-26"><span class="msubsup" id="MathJax-Span-27"><span style="display: inline-block; position: relative; width: 1.167em; height: 0px;"><span style="position: absolute; clip: rect(3.145em, 1000.76em, 4.149em, -1000em); top: -3.987em; left: 0em;"><span class="mi" id="MathJax-Span-28" style="font-family: MathJax_Math; font-style: italic;">E<span style="display: inline-block; overflow: hidden; height: 1px; width: 0.026em;"></span></span><span style="display: inline-block; width: 0px; height: 3.987em;"></span></span><span style="position: absolute; top: -3.837em; left: 0.738em;"><span class="mn" id="MathJax-Span-29" style="font-size: 70.7%; font-family: MathJax_Main;">1</span><span style="display: inline-block; width: 0px; height: 3.987em;"></span></span></span></span></span><span style="display: inline-block; width: 0px; height: 2.425em;"></span></span></span><span style="display: inline-block; overflow: hidden; vertical-align: -0.236em; border-left: 0px solid; width: 0px; height: 1.088em;"></span></span></nobr><span class="MJX_Assistive_MathML" role="presentation"><math xmlns="http://www.w3.org/1998/Math/MathML"><msub><mi>E</mi><mn>1</mn></msub></math></span></span><script type="math/tex" id="MathJax-Element-7">E_1</script></span>, <span class="mathjax"><span class="MathJax_Preview" style="color: inherit; display: none;"></span><span class="MathJax" id="MathJax-Element-8-Frame" tabindex="0" style="position: relative;" data-mathml="<math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;><msub><mi>E</mi><mn>2</mn></msub></math>" role="presentation"><nobr aria-hidden="true"><span class="math" id="MathJax-Span-30" style="width: 1.404em; display: inline-block;"><span style="display: inline-block; position: relative; width: 1.185em; height: 0px; font-size: 116%;"><span style="position: absolute; clip: rect(1.583em, 1001.18em, 2.736em, -1000em); top: -2.425em; left: 0em;"><span class="mrow" id="MathJax-Span-31"><span class="msubsup" id="MathJax-Span-32"><span style="display: inline-block; position: relative; width: 1.167em; height: 0px;"><span style="position: absolute; clip: rect(3.145em, 1000.76em, 4.149em, -1000em); top: -3.987em; left: 0em;"><span class="mi" id="MathJax-Span-33" style="font-family: MathJax_Math; font-style: italic;">E<span style="display: inline-block; overflow: hidden; height: 1px; width: 0.026em;"></span></span><span style="display: inline-block; width: 0px; height: 3.987em;"></span></span><span style="position: absolute; top: -3.837em; left: 0.738em;"><span class="mn" id="MathJax-Span-34" style="font-size: 70.7%; font-family: MathJax_Main;">2</span><span style="display: inline-block; width: 0px; height: 3.987em;"></span></span></span></span></span><span style="display: inline-block; width: 0px; height: 2.425em;"></span></span></span><span style="display: inline-block; overflow: hidden; vertical-align: -0.236em; border-left: 0px solid; width: 0px; height: 1.088em;"></span></span></nobr><span class="MJX_Assistive_MathML" role="presentation"><math xmlns="http://www.w3.org/1998/Math/MathML"><msub><mi>E</mi><mn>2</mn></msub></math></span></span><script type="math/tex" id="MathJax-Element-8">E_2</script></span>, …, <span class="mathjax"><span class="MathJax_Preview" style="color: inherit; display: none;"></span><span class="MathJax" id="MathJax-Element-9-Frame" tabindex="0" style="position: relative;" data-mathml="<math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;><msub><mi>E</mi><mi>n</mi></msub></math>" role="presentation"><nobr aria-hidden="true"><span class="math" id="MathJax-Span-35" style="width: 1.457em; display: inline-block;"><span style="display: inline-block; position: relative; width: 1.239em; height: 0px; font-size: 116%;"><span style="position: absolute; clip: rect(1.583em, 1001.24em, 2.744em, -1000em); top: -2.425em; left: 0em;"><span class="mrow" id="MathJax-Span-36"><span class="msubsup" id="MathJax-Span-37"><span style="display: inline-block; position: relative; width: 1.237em; height: 0px;"><span style="position: absolute; clip: rect(3.145em, 1000.76em, 4.149em, -1000em); top: -3.987em; left: 0em;"><span class="mi" id="MathJax-Span-38" style="font-family: MathJax_Math; font-style: italic;">E<span style="display: inline-block; overflow: hidden; height: 1px; width: 0.026em;"></span></span><span style="display: inline-block; width: 0px; height: 3.987em;"></span></span><span style="position: absolute; top: -3.837em; left: 0.738em;"><span class="mi" id="MathJax-Span-39" style="font-size: 70.7%; font-family: MathJax_Math; font-style: italic;">n</span><span style="display: inline-block; width: 0px; height: 3.987em;"></span></span></span></span></span><span style="display: inline-block; width: 0px; height: 2.425em;"></span></span></span><span style="display: inline-block; overflow: hidden; vertical-align: -0.246em; border-left: 0px solid; width: 0px; height: 1.097em;"></span></span></nobr><span class="MJX_Assistive_MathML" role="presentation"><math xmlns="http://www.w3.org/1998/Math/MathML"><msub><mi>E</mi><mi>n</mi></msub></math></span></span><script type="math/tex" id="MathJax-Element-9">E_n</script></span> be those <em>initializer-clauses</em> in order, <span class="mathjax"><span class="MathJax_Preview" style="color: inherit; display: none;"></span><span class="MathJax" id="MathJax-Element-10-Frame" tabindex="0" style="position: relative;" data-mathml="<math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;><msub><mi>C</mi><mn>1</mn></msub></math>" role="presentation"><nobr aria-hidden="true"><span class="math" id="MathJax-Span-40" style="width: 1.35em; display: inline-block;"><span style="display: inline-block; position: relative; width: 1.131em; height: 0px; font-size: 116%;"><span style="position: absolute; clip: rect(1.558em, 1001.13em, 2.736em, -1000em); top: -2.425em; left: 0em;"><span class="mrow" id="MathJax-Span-41"><span class="msubsup" id="MathJax-Span-42"><span style="display: inline-block; position: relative; width: 1.144em; height: 0px;"><span style="position: absolute; clip: rect(3.12em, 1000.76em, 4.171em, -1000em); top: -3.987em; left: 0em;"><span class="mi" id="MathJax-Span-43" style="font-family: MathJax_Math; font-style: italic;">C<span style="display: inline-block; overflow: hidden; height: 1px; width: 0.045em;"></span></span><span style="display: inline-block; width: 0px; height: 3.987em;"></span></span><span style="position: absolute; top: -3.837em; left: 0.715em;"><span class="mn" id="MathJax-Span-44" style="font-size: 70.7%; font-family: MathJax_Main;">1</span><span style="display: inline-block; width: 0px; height: 3.987em;"></span></span></span></span></span><span style="display: inline-block; width: 0px; height: 2.425em;"></span></span></span><span style="display: inline-block; overflow: hidden; vertical-align: -0.236em; border-left: 0px solid; width: 0px; height: 1.117em;"></span></span></nobr><span class="MJX_Assistive_MathML" role="presentation"><math xmlns="http://www.w3.org/1998/Math/MathML"><msub><mi>C</mi><mn>1</mn></msub></math></span></span><script type="math/tex" id="MathJax-Element-10">C_1</script></span>, <span class="mathjax"><span class="MathJax_Preview" style="color: inherit; display: none;"></span><span class="MathJax" id="MathJax-Element-11-Frame" tabindex="0" style="position: relative;" data-mathml="<math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;><msub><mi>C</mi><mn>2</mn></msub></math>" role="presentation"><nobr aria-hidden="true"><span class="math" id="MathJax-Span-45" style="width: 1.35em; display: inline-block;"><span style="display: inline-block; position: relative; width: 1.131em; height: 0px; font-size: 116%;"><span style="position: absolute; clip: rect(1.558em, 1001.13em, 2.736em, -1000em); top: -2.425em; left: 0em;"><span class="mrow" id="MathJax-Span-46"><span class="msubsup" id="MathJax-Span-47"><span style="display: inline-block; position: relative; width: 1.144em; height: 0px;"><span style="position: absolute; clip: rect(3.12em, 1000.76em, 4.171em, -1000em); top: -3.987em; left: 0em;"><span class="mi" id="MathJax-Span-48" style="font-family: MathJax_Math; font-style: italic;">C<span style="display: inline-block; overflow: hidden; height: 1px; width: 0.045em;"></span></span><span style="display: inline-block; width: 0px; height: 3.987em;"></span></span><span style="position: absolute; top: -3.837em; left: 0.715em;"><span class="mn" id="MathJax-Span-49" style="font-size: 70.7%; font-family: MathJax_Main;">2</span><span style="display: inline-block; width: 0px; height: 3.987em;"></span></span></span></span></span><span style="display: inline-block; width: 0px; height: 2.425em;"></span></span></span><span style="display: inline-block; overflow: hidden; vertical-align: -0.236em; border-left: 0px solid; width: 0px; height: 1.117em;"></span></span></nobr><span class="MJX_Assistive_MathML" role="presentation"><math xmlns="http://www.w3.org/1998/Math/MathML"><msub><mi>C</mi><mn>2</mn></msub></math></span></span><script type="math/tex" id="MathJax-Element-11">C_2</script></span>, …, <span class="mathjax"><span class="MathJax_Preview" style="color: inherit; display: none;"></span><span class="MathJax" id="MathJax-Element-12-Frame" tabindex="0" style="position: relative;" data-mathml="<math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;><msub><mi>C</mi><mi>m</mi></msub></math>" role="presentation"><nobr aria-hidden="true"><span class="math" id="MathJax-Span-50" style="width: 1.619em; display: inline-block;"><span style="display: inline-block; position: relative; width: 1.401em; height: 0px; font-size: 116%;"><span style="position: absolute; clip: rect(1.558em, 1001.4em, 2.744em, -1000em); top: -2.425em; left: 0em;"><span class="mrow" id="MathJax-Span-51"><span class="msubsup" id="MathJax-Span-52"><span style="display: inline-block; position: relative; width: 1.411em; height: 0px;"><span style="position: absolute; clip: rect(3.12em, 1000.76em, 4.171em, -1000em); top: -3.987em; left: 0em;"><span class="mi" id="MathJax-Span-53" style="font-family: MathJax_Math; font-style: italic;">C<span style="display: inline-block; overflow: hidden; height: 1px; width: 0.045em;"></span></span><span style="display: inline-block; width: 0px; height: 3.987em;"></span></span><span style="position: absolute; top: -3.837em; left: 0.715em;"><span class="mi" id="MathJax-Span-54" style="font-size: 70.7%; font-family: MathJax_Math; font-style: italic;">m</span><span style="display: inline-block; width: 0px; height: 3.987em;"></span></span></span></span></span><span style="display: inline-block; width: 0px; height: 2.425em;"></span></span></span><span style="display: inline-block; overflow: hidden; vertical-align: -0.246em; border-left: 0px solid; width: 0px; height: 1.126em;"></span></span></nobr><span class="MJX_Assistive_MathML" role="presentation"><math xmlns="http://www.w3.org/1998/Math/MathML"><msub><mi>C</mi><mi>m</mi></msub></math></span></span><script type="math/tex" id="MathJax-Element-12">C_m</script></span> be the <em>constrained-type-declarators</em> of all the mentioned <em>constrained-type-names</em>.  Given the following invented class template,</p>
<p><code>template&lt;</code><span class="mathjax"><span class="MathJax_Preview" style="color: inherit; display: none;"></span><span class="MathJax" id="MathJax-Element-13-Frame" tabindex="0" style="position: relative;" data-mathml="<math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;><msub><mi>C</mi><mn>1</mn></msub></math>" role="presentation"><nobr aria-hidden="true"><span class="math" id="MathJax-Span-55" style="width: 1.35em; display: inline-block;"><span style="display: inline-block; position: relative; width: 1.131em; height: 0px; font-size: 116%;"><span style="position: absolute; clip: rect(1.558em, 1001.13em, 2.736em, -1000em); top: -2.425em; left: 0em;"><span class="mrow" id="MathJax-Span-56"><span class="msubsup" id="MathJax-Span-57"><span style="display: inline-block; position: relative; width: 1.144em; height: 0px;"><span style="position: absolute; clip: rect(3.12em, 1000.76em, 4.171em, -1000em); top: -3.987em; left: 0em;"><span class="mi" id="MathJax-Span-58" style="font-family: MathJax_Math; font-style: italic;">C<span style="display: inline-block; overflow: hidden; height: 1px; width: 0.045em;"></span></span><span style="display: inline-block; width: 0px; height: 3.987em;"></span></span><span style="position: absolute; top: -3.837em; left: 0.715em;"><span class="mn" id="MathJax-Span-59" style="font-size: 70.7%; font-family: MathJax_Main;">1</span><span style="display: inline-block; width: 0px; height: 3.987em;"></span></span></span></span></span><span style="display: inline-block; width: 0px; height: 2.425em;"></span></span></span><span style="display: inline-block; overflow: hidden; vertical-align: -0.236em; border-left: 0px solid; width: 0px; height: 1.117em;"></span></span></nobr><span class="MJX_Assistive_MathML" role="presentation"><math xmlns="http://www.w3.org/1998/Math/MathML"><msub><mi>C</mi><mn>1</mn></msub></math></span></span><script type="math/tex" id="MathJax-Element-13">C_1</script></span>, <span class="mathjax"><span class="MathJax_Preview" style="color: inherit; display: none;"></span><span class="MathJax" id="MathJax-Element-14-Frame" tabindex="0" style="position: relative;" data-mathml="<math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;><msub><mi>C</mi><mn>2</mn></msub></math>" role="presentation"><nobr aria-hidden="true"><span class="math" id="MathJax-Span-60" style="width: 1.35em; display: inline-block;"><span style="display: inline-block; position: relative; width: 1.131em; height: 0px; font-size: 116%;"><span style="position: absolute; clip: rect(1.558em, 1001.13em, 2.736em, -1000em); top: -2.425em; left: 0em;"><span class="mrow" id="MathJax-Span-61"><span class="msubsup" id="MathJax-Span-62"><span style="display: inline-block; position: relative; width: 1.144em; height: 0px;"><span style="position: absolute; clip: rect(3.12em, 1000.76em, 4.171em, -1000em); top: -3.987em; left: 0em;"><span class="mi" id="MathJax-Span-63" style="font-family: MathJax_Math; font-style: italic;">C<span style="display: inline-block; overflow: hidden; height: 1px; width: 0.045em;"></span></span><span style="display: inline-block; width: 0px; height: 3.987em;"></span></span><span style="position: absolute; top: -3.837em; left: 0.715em;"><span class="mn" id="MathJax-Span-64" style="font-size: 70.7%; font-family: MathJax_Main;">2</span><span style="display: inline-block; width: 0px; height: 3.987em;"></span></span></span></span></span><span style="display: inline-block; width: 0px; height: 2.425em;"></span></span></span><span style="display: inline-block; overflow: hidden; vertical-align: -0.236em; border-left: 0px solid; width: 0px; height: 1.117em;"></span></span></nobr><span class="MJX_Assistive_MathML" role="presentation"><math xmlns="http://www.w3.org/1998/Math/MathML"><msub><mi>C</mi><mn>2</mn></msub></math></span></span><script type="math/tex" id="MathJax-Element-14">C_2</script></span>, …, <span class="mathjax"><span class="MathJax_Preview" style="color: inherit; display: none;"></span><span class="MathJax" id="MathJax-Element-15-Frame" tabindex="0" style="position: relative;" data-mathml="<math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;><msub><mi>C</mi><mi>m</mi></msub></math>" role="presentation"><nobr aria-hidden="true"><span class="math" id="MathJax-Span-65" style="width: 1.619em; display: inline-block;"><span style="display: inline-block; position: relative; width: 1.401em; height: 0px; font-size: 116%;"><span style="position: absolute; clip: rect(1.558em, 1001.4em, 2.744em, -1000em); top: -2.425em; left: 0em;"><span class="mrow" id="MathJax-Span-66"><span class="msubsup" id="MathJax-Span-67"><span style="display: inline-block; position: relative; width: 1.411em; height: 0px;"><span style="position: absolute; clip: rect(3.12em, 1000.76em, 4.171em, -1000em); top: -3.987em; left: 0em;"><span class="mi" id="MathJax-Span-68" style="font-family: MathJax_Math; font-style: italic;">C<span style="display: inline-block; overflow: hidden; height: 1px; width: 0.045em;"></span></span><span style="display: inline-block; width: 0px; height: 3.987em;"></span></span><span style="position: absolute; top: -3.837em; left: 0.715em;"><span class="mi" id="MathJax-Span-69" style="font-size: 70.7%; font-family: MathJax_Math; font-style: italic;">m</span><span style="display: inline-block; width: 0px; height: 3.987em;"></span></span></span></span></span><span style="display: inline-block; width: 0px; height: 2.425em;"></span></span></span><span style="display: inline-block; overflow: hidden; vertical-align: -0.246em; border-left: 0px solid; width: 0px; height: 1.126em;"></span></span></nobr><span class="MJX_Assistive_MathML" role="presentation"><math xmlns="http://www.w3.org/1998/Math/MathML"><msub><mi>C</mi><mi>m</mi></msub></math></span></span><script type="math/tex" id="MathJax-Element-15">C_m</script></span><code>&gt;</code><br>
<code>struct f { f(</code><span class="mathjax"><span class="MathJax_Preview" style="color: inherit; display: none;"></span><span class="MathJax" id="MathJax-Element-16-Frame" tabindex="0" style="position: relative;" data-mathml="<math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;><mi>D</mi></math>" role="presentation"><nobr aria-hidden="true"><span class="math" id="MathJax-Span-70" style="width: 0.973em; display: inline-block;"><span style="display: inline-block; position: relative; width: 0.808em; height: 0px; font-size: 116%;"><span style="position: absolute; clip: rect(1.634em, 1000.78em, 2.64em, -1000em); top: -2.478em; left: 0em;"><span class="mrow" id="MathJax-Span-71"><span class="mi" id="MathJax-Span-72" style="font-family: MathJax_Math; font-style: italic;">D</span></span><span style="display: inline-block; width: 0px; height: 2.478em;"></span></span></span><span style="display: inline-block; overflow: hidden; vertical-align: -0.063em; border-left: 0px solid; width: 0px; height: 0.917em;"></span></span></nobr><span class="MJX_Assistive_MathML" role="presentation"><math xmlns="http://www.w3.org/1998/Math/MathML"><mi>D</mi></math></span></span><script type="math/tex" id="MathJax-Element-16">D</script></span> <span class="mathjax"><span class="MathJax_Preview" style="color: inherit; display: none;"></span><span class="MathJax" id="MathJax-Element-17-Frame" tabindex="0" style="position: relative;" data-mathml="<math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;><msub><mi>I</mi><mn>1</mn></msub></math>" role="presentation"><nobr aria-hidden="true"><span class="math" id="MathJax-Span-73" style="width: 1.026em; display: inline-block;"><span style="display: inline-block; position: relative; width: 0.862em; height: 0px; font-size: 116%;"><span style="position: absolute; clip: rect(1.58em, 1000.86em, 2.736em, -1000em); top: -2.425em; left: 0em;"><span class="mrow" id="MathJax-Span-74"><span class="msubsup" id="MathJax-Span-75"><span style="display: inline-block; position: relative; width: 0.869em; height: 0px;"><span style="position: absolute; clip: rect(3.142em, 1000.5em, 4.149em, -1000em); top: -3.987em; left: 0em;"><span class="mi" id="MathJax-Span-76" style="font-family: MathJax_Math; font-style: italic;">I<span style="display: inline-block; overflow: hidden; height: 1px; width: 0.064em;"></span></span><span style="display: inline-block; width: 0px; height: 3.987em;"></span></span><span style="position: absolute; top: -3.837em; left: 0.44em;"><span class="mn" id="MathJax-Span-77" style="font-size: 70.7%; font-family: MathJax_Main;">1</span><span style="display: inline-block; width: 0px; height: 3.987em;"></span></span></span></span></span><span style="display: inline-block; width: 0px; height: 2.425em;"></span></span></span><span style="display: inline-block; overflow: hidden; vertical-align: -0.236em; border-left: 0px solid; width: 0px; height: 1.091em;"></span></span></nobr><span class="MJX_Assistive_MathML" role="presentation"><math xmlns="http://www.w3.org/1998/Math/MathML"><msub><mi>I</mi><mn>1</mn></msub></math></span></span><script type="math/tex" id="MathJax-Element-17">I_1</script></span>, <span class="mathjax"><span class="MathJax_Preview" style="color: inherit; display: none;"></span><span class="MathJax" id="MathJax-Element-18-Frame" tabindex="0" style="position: relative;" data-mathml="<math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;><mi>D</mi></math>" role="presentation"><nobr aria-hidden="true"><span class="math" id="MathJax-Span-78" style="width: 0.973em; display: inline-block;"><span style="display: inline-block; position: relative; width: 0.808em; height: 0px; font-size: 116%;"><span style="position: absolute; clip: rect(1.634em, 1000.78em, 2.64em, -1000em); top: -2.478em; left: 0em;"><span class="mrow" id="MathJax-Span-79"><span class="mi" id="MathJax-Span-80" style="font-family: MathJax_Math; font-style: italic;">D</span></span><span style="display: inline-block; width: 0px; height: 2.478em;"></span></span></span><span style="display: inline-block; overflow: hidden; vertical-align: -0.063em; border-left: 0px solid; width: 0px; height: 0.917em;"></span></span></nobr><span class="MJX_Assistive_MathML" role="presentation"><math xmlns="http://www.w3.org/1998/Math/MathML"><mi>D</mi></math></span></span><script type="math/tex" id="MathJax-Element-18">D</script></span> <span class="mathjax"><span class="MathJax_Preview" style="color: inherit; display: none;"></span><span class="MathJax" id="MathJax-Element-19-Frame" tabindex="0" style="position: relative;" data-mathml="<math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;><msub><mi>I</mi><mn>2</mn></msub></math>" role="presentation"><nobr aria-hidden="true"><span class="math" id="MathJax-Span-81" style="width: 1.026em; display: inline-block;"><span style="display: inline-block; position: relative; width: 0.862em; height: 0px; font-size: 116%;"><span style="position: absolute; clip: rect(1.58em, 1000.86em, 2.736em, -1000em); top: -2.425em; left: 0em;"><span class="mrow" id="MathJax-Span-82"><span class="msubsup" id="MathJax-Span-83"><span style="display: inline-block; position: relative; width: 0.869em; height: 0px;"><span style="position: absolute; clip: rect(3.142em, 1000.5em, 4.149em, -1000em); top: -3.987em; left: 0em;"><span class="mi" id="MathJax-Span-84" style="font-family: MathJax_Math; font-style: italic;">I<span style="display: inline-block; overflow: hidden; height: 1px; width: 0.064em;"></span></span><span style="display: inline-block; width: 0px; height: 3.987em;"></span></span><span style="position: absolute; top: -3.837em; left: 0.44em;"><span class="mn" id="MathJax-Span-85" style="font-size: 70.7%; font-family: MathJax_Main;">2</span><span style="display: inline-block; width: 0px; height: 3.987em;"></span></span></span></span></span><span style="display: inline-block; width: 0px; height: 2.425em;"></span></span></span><span style="display: inline-block; overflow: hidden; vertical-align: -0.236em; border-left: 0px solid; width: 0px; height: 1.091em;"></span></span></nobr><span class="MJX_Assistive_MathML" role="presentation"><math xmlns="http://www.w3.org/1998/Math/MathML"><msub><mi>I</mi><mn>2</mn></msub></math></span></span><script type="math/tex" id="MathJax-Element-19">I_2</script></span>, …, <span class="mathjax"><span class="MathJax_Preview" style="color: inherit; display: none;"></span><span class="MathJax" id="MathJax-Element-20-Frame" tabindex="0" style="position: relative;" data-mathml="<math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;><mi>D</mi></math>" role="presentation"><nobr aria-hidden="true"><span class="math" id="MathJax-Span-86" style="width: 0.973em; display: inline-block;"><span style="display: inline-block; position: relative; width: 0.808em; height: 0px; font-size: 116%;"><span style="position: absolute; clip: rect(1.634em, 1000.78em, 2.64em, -1000em); top: -2.478em; left: 0em;"><span class="mrow" id="MathJax-Span-87"><span class="mi" id="MathJax-Span-88" style="font-family: MathJax_Math; font-style: italic;">D</span></span><span style="display: inline-block; width: 0px; height: 2.478em;"></span></span></span><span style="display: inline-block; overflow: hidden; vertical-align: -0.063em; border-left: 0px solid; width: 0px; height: 0.917em;"></span></span></nobr><span class="MJX_Assistive_MathML" role="presentation"><math xmlns="http://www.w3.org/1998/Math/MathML"><mi>D</mi></math></span></span><script type="math/tex" id="MathJax-Element-20">D</script></span> <span class="mathjax"><span class="MathJax_Preview" style="color: inherit; display: none;"></span><span class="MathJax" id="MathJax-Element-21-Frame" tabindex="0" style="position: relative;" data-mathml="<math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;><msub><mi>I</mi><mi>n</mi></msub></math>" role="presentation"><nobr aria-hidden="true"><span class="math" id="MathJax-Span-89" style="width: 1.08em; display: inline-block;"><span style="display: inline-block; position: relative; width: 0.916em; height: 0px; font-size: 116%;"><span style="position: absolute; clip: rect(1.58em, 1000.92em, 2.744em, -1000em); top: -2.425em; left: 0em;"><span class="mrow" id="MathJax-Span-90"><span class="msubsup" id="MathJax-Span-91"><span style="display: inline-block; position: relative; width: 0.939em; height: 0px;"><span style="position: absolute; clip: rect(3.142em, 1000.5em, 4.149em, -1000em); top: -3.987em; left: 0em;"><span class="mi" id="MathJax-Span-92" style="font-family: MathJax_Math; font-style: italic;">I<span style="display: inline-block; overflow: hidden; height: 1px; width: 0.064em;"></span></span><span style="display: inline-block; width: 0px; height: 3.987em;"></span></span><span style="position: absolute; top: -3.837em; left: 0.44em;"><span class="mi" id="MathJax-Span-93" style="font-size: 70.7%; font-family: MathJax_Math; font-style: italic;">n</span><span style="display: inline-block; width: 0px; height: 3.987em;"></span></span></span></span></span><span style="display: inline-block; width: 0px; height: 2.425em;"></span></span></span><span style="display: inline-block; overflow: hidden; vertical-align: -0.246em; border-left: 0px solid; width: 0px; height: 1.1em;"></span></span></nobr><span class="MJX_Assistive_MathML" role="presentation"><math xmlns="http://www.w3.org/1998/Math/MathML"><msub><mi>I</mi><mi>n</mi></msub></math></span></span><script type="math/tex" id="MathJax-Element-21">I_n</script></span><code>); };</code></p>
<p>the <em>constrained-type-names</em> are <em>bounded</em> to be the types of the template arguments that are deduced from the call <code>f(</code><span class="mathjax"><span class="MathJax_Preview" style="color: inherit; display: none;"></span><span class="MathJax" id="MathJax-Element-22-Frame" tabindex="0" style="position: relative;" data-mathml="<math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;><msub><mi>E</mi><mn>1</mn></msub></math>" role="presentation"><nobr aria-hidden="true"><span class="math" id="MathJax-Span-94" style="width: 1.404em; display: inline-block;"><span style="display: inline-block; position: relative; width: 1.185em; height: 0px; font-size: 116%;"><span style="position: absolute; clip: rect(1.583em, 1001.18em, 2.736em, -1000em); top: -2.425em; left: 0em;"><span class="mrow" id="MathJax-Span-95"><span class="msubsup" id="MathJax-Span-96"><span style="display: inline-block; position: relative; width: 1.167em; height: 0px;"><span style="position: absolute; clip: rect(3.145em, 1000.76em, 4.149em, -1000em); top: -3.987em; left: 0em;"><span class="mi" id="MathJax-Span-97" style="font-family: MathJax_Math; font-style: italic;">E<span style="display: inline-block; overflow: hidden; height: 1px; width: 0.026em;"></span></span><span style="display: inline-block; width: 0px; height: 3.987em;"></span></span><span style="position: absolute; top: -3.837em; left: 0.738em;"><span class="mn" id="MathJax-Span-98" style="font-size: 70.7%; font-family: MathJax_Main;">1</span><span style="display: inline-block; width: 0px; height: 3.987em;"></span></span></span></span></span><span style="display: inline-block; width: 0px; height: 2.425em;"></span></span></span><span style="display: inline-block; overflow: hidden; vertical-align: -0.236em; border-left: 0px solid; width: 0px; height: 1.088em;"></span></span></nobr><span class="MJX_Assistive_MathML" role="presentation"><math xmlns="http://www.w3.org/1998/Math/MathML"><msub><mi>E</mi><mn>1</mn></msub></math></span></span><script type="math/tex" id="MathJax-Element-22">E_1</script></span>, <span class="mathjax"><span class="MathJax_Preview" style="color: inherit; display: none;"></span><span class="MathJax" id="MathJax-Element-23-Frame" tabindex="0" style="position: relative;" data-mathml="<math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;><msub><mi>E</mi><mn>2</mn></msub></math>" role="presentation"><nobr aria-hidden="true"><span class="math" id="MathJax-Span-99" style="width: 1.404em; display: inline-block;"><span style="display: inline-block; position: relative; width: 1.185em; height: 0px; font-size: 116%;"><span style="position: absolute; clip: rect(1.583em, 1001.18em, 2.736em, -1000em); top: -2.425em; left: 0em;"><span class="mrow" id="MathJax-Span-100"><span class="msubsup" id="MathJax-Span-101"><span style="display: inline-block; position: relative; width: 1.167em; height: 0px;"><span style="position: absolute; clip: rect(3.145em, 1000.76em, 4.149em, -1000em); top: -3.987em; left: 0em;"><span class="mi" id="MathJax-Span-102" style="font-family: MathJax_Math; font-style: italic;">E<span style="display: inline-block; overflow: hidden; height: 1px; width: 0.026em;"></span></span><span style="display: inline-block; width: 0px; height: 3.987em;"></span></span><span style="position: absolute; top: -3.837em; left: 0.738em;"><span class="mn" id="MathJax-Span-103" style="font-size: 70.7%; font-family: MathJax_Main;">2</span><span style="display: inline-block; width: 0px; height: 3.987em;"></span></span></span></span></span><span style="display: inline-block; width: 0px; height: 2.425em;"></span></span></span><span style="display: inline-block; overflow: hidden; vertical-align: -0.236em; border-left: 0px solid; width: 0px; height: 1.088em;"></span></span></nobr><span class="MJX_Assistive_MathML" role="presentation"><math xmlns="http://www.w3.org/1998/Math/MathML"><msub><mi>E</mi><mn>2</mn></msub></math></span></span><script type="math/tex" id="MathJax-Element-23">E_2</script></span>, …, <span class="mathjax"><span class="MathJax_Preview" style="color: inherit; display: none;"></span><span class="MathJax" id="MathJax-Element-24-Frame" tabindex="0" style="position: relative;" data-mathml="<math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;><msub><mi>E</mi><mi>n</mi></msub></math>" role="presentation"><nobr aria-hidden="true"><span class="math" id="MathJax-Span-104" style="width: 1.457em; display: inline-block;"><span style="display: inline-block; position: relative; width: 1.239em; height: 0px; font-size: 116%;"><span style="position: absolute; clip: rect(1.583em, 1001.24em, 2.744em, -1000em); top: -2.425em; left: 0em;"><span class="mrow" id="MathJax-Span-105"><span class="msubsup" id="MathJax-Span-106"><span style="display: inline-block; position: relative; width: 1.237em; height: 0px;"><span style="position: absolute; clip: rect(3.145em, 1000.76em, 4.149em, -1000em); top: -3.987em; left: 0em;"><span class="mi" id="MathJax-Span-107" style="font-family: MathJax_Math; font-style: italic;">E<span style="display: inline-block; overflow: hidden; height: 1px; width: 0.026em;"></span></span><span style="display: inline-block; width: 0px; height: 3.987em;"></span></span><span style="position: absolute; top: -3.837em; left: 0.738em;"><span class="mi" id="MathJax-Span-108" style="font-size: 70.7%; font-family: MathJax_Math; font-style: italic;">n</span><span style="display: inline-block; width: 0px; height: 3.987em;"></span></span></span></span></span><span style="display: inline-block; width: 0px; height: 2.425em;"></span></span></span><span style="display: inline-block; overflow: hidden; vertical-align: -0.246em; border-left: 0px solid; width: 0px; height: 1.097em;"></span></span></nobr><span class="MJX_Assistive_MathML" role="presentation"><math xmlns="http://www.w3.org/1998/Math/MathML"><msub><mi>E</mi><mi>n</mi></msub></math></span></span><script type="math/tex" id="MathJax-Element-24">E_n</script></span><code>)</code> as an unevaluated operand.  If the class template or the call is ill-formed, the program is ill-formed.</p>
<p>Any use of a <em>constrained-type-name</em> refers to the bounded type; if the <em>constrained-type-name</em> is not bounded at the point of use or bounded to more than one type, the program is ill-formed.</p>
</blockquote><p>Examples (not concerning forwarding references):</p><p>Given</p><pre><code class="c++ hljs"><span class="hljs-attribute">Copyable</span> T;
<span class="hljs-attribute">Iterator</span> A, Copyable B;
</code></pre><p>for</p><pre><code class="c++ hljs"><span class="hljs-attribute">T</span> a[] = <span class="hljs-string">"meow"</span>;
</code></pre><p>we form</p><pre><code class="c++ hljs"><span class="hljs-keyword">template</span>&lt;Copyable T&gt;
<span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">f</span><span class="hljs-params">(T a[])</span></span>;
</code></pre><p>Calling <code>f("meow")</code> deduces <code>T</code> to <code>char</code>, so the original declaration becomes</p><pre><code class="c++ hljs"><span class="hljs-keyword">char</span> a[] = <span class="hljs-string">"meow"</span>;
</code></pre><p>For</p><pre><code class="c++ hljs">tuple<span class="hljs-tag">&lt;<span class="hljs-name">T*,</span> <span class="hljs-attr">int</span>&gt;</span> b;
tuple<span class="hljs-tag">&lt;<span class="hljs-name">A,</span> <span class="hljs-attr">B</span>&gt;</span> &amp;r = b, c = tuple(a, 3);
</code></pre><p>we form</p><pre><code class="c++ hljs"><span class="hljs-keyword">template</span>&lt;Iterator A, Copyable B&gt;
<span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">f</span><span class="hljs-params">(tuple&lt;A, B&gt; &amp;r, tuple&lt;A, B&gt; c)</span></span>;
</code></pre><p>Calling <code>f(b, tuple(a, 3))</code> gives <code>A = char*</code> and <code>B = int</code>.</p><h2 id="Comparing-with-Other-Proposals" style=""><a class="anchor hidden-xs" href="#Comparing-with-Other-Proposals" title="Comparing-with-Other-Proposals"><span class="octicon octicon-link"></span></a>Comparing with Other Proposals</h2><p>There have been a few proposals that can address the motivation of this paper: Concepts TS<sup class="footnote-ref"><a href="#fn3" id="fnref3">[3]</a></sup>, in-place syntax<sup class="footnote-ref"><a href="#fn4" id="fnref4">[4]</a></sup>, constrained <code>auto</code><sup class="footnote-ref"><a href="#fn1" id="fnref1:1">[1:1]</a></sup>, and YAACD<sup class="footnote-ref"><a href="#fn5" id="fnref5">[5]</a></sup>.  The in-place syntax extends the <em>constrained-type-specifier</em> from the Concepts TS by allowing optional in-place type names, so I will call their common parts “<em>constrained-type-specifier</em>” and discuss the “in-place syntax” separately.  YAACD part 1 and constrained <code>auto</code> differ only in syntax so that I will group them into “constrained <code>auto</code>.”  The part 2 makes the syntax compatible with the simple case (a single <em>decl-specifier</em> that is a <em>qualified-concept-name</em>) of Concepts TS so that I will skip this part.</p><p>The <em>constrained-type-specifier</em> has two set of rules for deduction, one for simple cases,</p><pre><code class="c++ hljs"><span class="hljs-attribute">Copyable</span> &amp;&amp;a = foo();
</code></pre><p>and one for complex cases:</p><pre><code class="c++ hljs">tuple<span class="hljs-tag">&lt;<span class="hljs-name">Iterator,</span> <span class="hljs-attr">Copyable</span>&gt;</span> c = make_tuple(a, 3);
</code></pre><p>In simple cases, deduction result backfills the type for the variable, so <code>&amp;&amp;</code> is treated as a forwarding reference; in complex cases, deduction result backfills the template parameters, so <code>&amp;&amp;</code> is treated as an rvalue reference.  This proposal, “concept-defined placeholder types” do not make this distinction and stick with the latter rule.  The other constrained <code>auto</code> proposals only handle the simple cases and use the former rule.</p><p>The in-place syntax and concept-defined placeholder types can naturally express consistent binding<sup class="footnote-ref"><a href="#fn6" id="fnref6">[6]</a></sup>,</p><pre><code class="c++ hljs"><span class="hljs-regexp">//</span> <span class="hljs-keyword">in</span>-place syntax
Copyable{T} a = foo();
tuple&lt;Copyable{T}&gt; b = bar();

<span class="hljs-regexp">//</span> <span class="hljs-keyword">this</span> paper
Copyable T;
T a = foo();
tuple&lt;T&gt; b = bar();
</code></pre><p><em>constrained-type-specifier</em> and constrained <code>auto</code> have no such flexibility.  The introduced type names can serve other purposes, for example, in</p><pre><code class="c++ hljs">Copyable{T} &amp;&amp;a = foo();
</code></pre><p>this <code>T</code> can replace <code>std::remove_cvref_t&lt;decltype(a)&gt;</code>.  The difference is that, in this proposal, introducing these type names are mandatory.  By doing so, we solved, simultaneously, the confusion (examples in §3.6<sup class="footnote-ref"><a href="#fn6" id="fnref6:1">[6:1]</a></sup>)</p><blockquote>
<blockquote>
<p>Independent resolution breaks the fundamental equivalence of the notations.</p>
</blockquote>
</blockquote><p>and the dilemma<sup class="footnote-ref"><a href="#fn7" id="fnref7">[7]</a></sup></p><blockquote>
<blockquote>
<p>We need a way of expressing “same type” for two uses of a concept.<br>
We need a way of saying “different type” for two uses of a concept.</p>
</blockquote>
</blockquote><p>raised in Bjarne’s papers.</p><p>The concept-defined placeholder types require a specific form of initialization (copy-initialization) to trigger deduction.  But it is hard to say whether it is a caveat or a feature, considering that none of the proposals attempt class template argument deduction from partially-specialized template argument lists<sup class="footnote-ref"><a href="#fn8" id="fnref8">[8]</a></sup>, which is implied by direct-initialization.</p><h2 id="Extensions" style=""><a class="anchor hidden-xs" href="#Extensions" title="Extensions"><span class="octicon octicon-link"></span></a>Extensions</h2><p>If we add multi-argument <em>constrained-parameters</em><sup class="footnote-ref"><a href="#fn9" id="fnref9">[9]</a></sup>,</p><pre><code class="c++ hljs"><span class="hljs-keyword">template</span> &lt;EqualityComparableWith T U&gt;
<span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">foo</span><span class="hljs-params">(T <span class="hljs-keyword">const</span>&amp; a, U <span class="hljs-keyword">const</span>&amp; b)</span>
</span>{
    <span class="hljs-keyword">if</span> (a == b)  <span class="hljs-comment">// must be valid</span>
</code></pre><p>we should also allow declaring multiple <em>constrained-type-names</em> that satisfy a multi-parameter concept at once:</p><pre><code class="c++ hljs">EqualityComparableWith T U;
T a = <span class="hljs-comment">/* ... */</span>;
U b = <span class="hljs-comment">/* ... */</span>;
<span class="hljs-keyword">if</span> (a == b)  <span class="hljs-comment">// must be valid</span>
</code></pre><p>We may also want to add parameter pack support.</p><h2 id="References" style=""><a class="anchor hidden-xs" href="#References" title="References"><span class="octicon octicon-link"></span></a>References</h2><hr class="footnotes-sep"><section class="footnotes">
<ol class="footnotes-list">
<li id="fn1" class="footnote-item"><p>Romeo, Vittorio, and John Lakos. P0915R0 <em>Concept-constrained auto</em>.
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0915r0.html" target="_blank">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0915r0.html</a> <a href="#fnref1" class="footnote-backref">↩︎</a> <a href="#fnref1:1" class="footnote-backref">↩︎</a></p>
</li>
<li id="fn2" class="footnote-item"><p>Voutilainen, Ville. N3897 <em>Auto-type members</em>.
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3897.html" target="_blank">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3897.html</a> <a href="#fnref2" class="footnote-backref">↩︎</a></p>
</li>
<li id="fn3" class="footnote-item"><p>Sutton, Andrew. N4674 <em>Working Draft, C++ extensions for Concepts</em>.
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/n4674.pdf" target="_blank">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/n4674.pdf</a> <a href="#fnref3" class="footnote-backref">↩︎</a></p>
</li>
<li id="fn4" class="footnote-item"><p>Sutter, Herb. P0745R1 <em>Concepts in-place syntax</em>.
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0745r1.pdf" target="_blank">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0745r1.pdf</a> <a href="#fnref4" class="footnote-backref">↩︎</a></p>
</li>
<li id="fn5" class="footnote-item"><p>Voutilainen, Ville, et al. P1141R0 <em>Yet another approach for constrained declarations</em>.
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1141r0.html" target="_blank">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1141r0.html</a> <a href="#fnref5" class="footnote-backref">↩︎</a></p>
</li>
<li id="fn6" class="footnote-item"><p>Stroustrup, Bjarne.  P0694R0 <em>Function declarations using concepts</em>.
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0694r0.pdf" target="_blank">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0694r0.pdf</a> <a href="#fnref6" class="footnote-backref">↩︎</a> <a href="#fnref6:1" class="footnote-backref">↩︎</a></p>
</li>
<li id="fn7" class="footnote-item"><p>Stroustrup, Bjarne. P0956R0 <em>Answers to concept syntax suggestions</em>.
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0956r0.pdf" target="_blank">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0956r0.pdf</a> <a href="#fnref7" class="footnote-backref">↩︎</a></p>
</li>
<li id="fn8" class="footnote-item"><p>Spertus, Mike.  P1021R0 <em>Extensions to Class Template Argument Deduction</em>.
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1021r0.html" target="_blank">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1021r0.html</a> <a href="#fnref8" class="footnote-backref">↩︎</a></p>
</li>
<li id="fn9" class="footnote-item"><p>Yuan, Zhihao.  P1157R0 <em>Multi-argument constrained-parameter</em>.
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1157r0.html" target="_blank">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1157r0.html</a> <a href="#fnref9" class="footnote-backref">↩︎</a></p>
</li>
</ol>
</section></div>
    <div class="ui-toc dropup unselectable hidden-print" style="display:none;">
        <div class="pull-right dropdown">
            <a id="tocLabel" class="ui-toc-label btn btn-default" data-toggle="dropdown" href="#" role="button" aria-haspopup="true" aria-expanded="false" title="Table of content">
                <i class="fa fa-bars"></i>
            </a>
            <ul id="ui-toc" class="ui-toc-dropdown dropdown-menu" aria-labelledby="tocLabel">
                <div class="toc"><ul class="nav"><li class=""><a href="#Concept-defined-placeholder-types" title="Concept-defined placeholder types">Concept-defined placeholder types</a><ul class="nav"><li><a href="#Motivation" title="Motivation">Motivation</a></li><li><a href="#Introduction" title="Introduction">Introduction</a></li><li><a href="#Design-Decisions" title="Design Decisions">Design Decisions</a></li><li><a href="#Technical-Description" title="Technical Description">Technical Description</a></li><li><a href="#Comparing-with-Other-Proposals" title="Comparing with Other Proposals">Comparing with Other Proposals</a></li><li><a href="#Extensions" title="Extensions">Extensions</a></li><li><a href="#References" title="References">References</a></li></ul></li></ul></div><div class="toc-menu"><a class="expand-toggle" href="#">Expand all</a><a class="back-to-top" href="#">Back to top</a><a class="go-to-bottom" href="#">Go to bottom</a></div>
            </ul>
        </div>
    </div>
    <div id="ui-toc-affix" class="ui-affix-toc ui-toc-dropdown unselectable hidden-print" data-spy="affix" style="top:17px;display:none;"  >
        <div class="toc"><ul class="nav"><li class=""><a href="#Concept-defined-placeholder-types" title="Concept-defined placeholder types">Concept-defined placeholder types</a><ul class="nav"><li><a href="#Motivation" title="Motivation">Motivation</a></li><li><a href="#Introduction" title="Introduction">Introduction</a></li><li><a href="#Design-Decisions" title="Design Decisions">Design Decisions</a></li><li><a href="#Technical-Description" title="Technical Description">Technical Description</a></li><li><a href="#Comparing-with-Other-Proposals" title="Comparing with Other Proposals">Comparing with Other Proposals</a></li><li><a href="#Extensions" title="Extensions">Extensions</a></li><li><a href="#References" title="References">References</a></li></ul></li></ul></div><div class="toc-menu"><a class="expand-toggle" href="#">Expand all</a><a class="back-to-top" href="#">Back to top</a><a class="go-to-bottom" href="#">Go to bottom</a></div>
    </div>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js" integrity="sha256-hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8=" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha256-U5ZEeKfGNOja007MMD3YBI0A3OSZOQbeG6z2f2Y0hu8=" crossorigin="anonymous" defer></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/gist-embed/2.6.0/gist-embed.min.js" integrity="sha256-KyF2D6xPIJUW5sUDSs93vWyZm+1RzIpKCexxElmxl8g=" crossorigin="anonymous" defer></script>
    <script>
        var markdown = $(".markdown-body");
        //smooth all hash trigger scrolling
        function smoothHashScroll() {
            var hashElements = $("a[href^='#']").toArray();
            for (var i = 0; i < hashElements.length; i++) {
                var element = hashElements[i];
                var $element = $(element);
                var hash = element.hash;
                if (hash) {
                    $element.on('click', function (e) {
                        // store hash
                        var hash = this.hash;
                        if ($(hash).length <= 0) return;
                        // prevent default anchor click behavior
                        e.preventDefault();
                        // animate
                        $('body, html').stop(true, true).animate({
                            scrollTop: $(hash).offset().top
                        }, 100, "linear", function () {
                            // when done, add hash to url
                            // (default click behaviour)
                            window.location.hash = hash;
                        });
                    });
                }
            }
        }

        smoothHashScroll();
        var toc = $('.ui-toc');
        var tocAffix = $('.ui-affix-toc');
        var tocDropdown = $('.ui-toc-dropdown');
        //toc
        tocDropdown.click(function (e) {
            e.stopPropagation();
        });

        var enoughForAffixToc = true;

        function generateScrollspy() {
            $(document.body).scrollspy({
                target: ''
            });
            $(document.body).scrollspy('refresh');
            if (enoughForAffixToc) {
                toc.hide();
                tocAffix.show();
            } else {
                tocAffix.hide();
                toc.show();
            }
            $(document.body).scroll();
        }

        function windowResize() {
            //toc right
            var paddingRight = parseFloat(markdown.css('padding-right'));
            var right = ($(window).width() - (markdown.offset().left + markdown.outerWidth() - paddingRight));
            toc.css('right', right + 'px');
            //affix toc left
            var newbool;
            var rightMargin = (markdown.parent().outerWidth() - markdown.outerWidth()) / 2;
            //for ipad or wider device
            if (rightMargin >= 133) {
                newbool = true;
                var affixLeftMargin = (tocAffix.outerWidth() - tocAffix.width()) / 2;
                var left = markdown.offset().left + markdown.outerWidth() - affixLeftMargin;
                tocAffix.css('left', left + 'px');
            } else {
                newbool = false;
            }
            if (newbool != enoughForAffixToc) {
                enoughForAffixToc = newbool;
                generateScrollspy();
            }
        }
        $(window).resize(function () {
            windowResize();
        });
        $(document).ready(function () {
            windowResize();
            generateScrollspy();
        });

        //remove hash
        function removeHash() {
            window.location.hash = '';
        }

        var backtotop = $('.back-to-top');
        var gotobottom = $('.go-to-bottom');

        backtotop.click(function (e) {
            e.preventDefault();
            e.stopPropagation();
            if (scrollToTop)
                scrollToTop();
            removeHash();
        });
        gotobottom.click(function (e) {
            e.preventDefault();
            e.stopPropagation();
            if (scrollToBottom)
                scrollToBottom();
            removeHash();
        });

        var toggle = $('.expand-toggle');
        var tocExpand = false;

        checkExpandToggle();
        toggle.click(function (e) {
            e.preventDefault();
            e.stopPropagation();
            tocExpand = !tocExpand;
            checkExpandToggle();
        })

        function checkExpandToggle () {
            var toc = $('.ui-toc-dropdown .toc');
            var toggle = $('.expand-toggle');
            if (!tocExpand) {
                toc.removeClass('expand');
                toggle.text('Expand all');
            } else {
                toc.addClass('expand');
                toggle.text('Collapse all');
            }
        }

        function scrollToTop() {
            $('body, html').stop(true, true).animate({
                scrollTop: 0
            }, 100, "linear");
        }

        function scrollToBottom() {
            $('body, html').stop(true, true).animate({
                scrollTop: $(document.body)[0].scrollHeight
            }, 100, "linear");
        }
    </script>
</body>

</html>
