<!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>
        auto(x): decay-copy in the language - 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://cdn.jsdelivr.net/npm/@hackmd/emojify.js@2.1.0/dist/css/basic/emojify.min.css" integrity="sha256-UOrvMOsSDSrW6szVLe8ZDZezBxh5IoIfgTwdNDgTjiU=" crossorigin="anonymous" />
    <style>
        @charset "UTF-8";@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-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 kbd,.popover 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}.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{padding-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}.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{padding-top:40px;padding-bottom:40px;max-width:758px;overflow:visible!important;position:relative}.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;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,.markdown-body pre.vega{text-align:center;background-color:inherit;border-radius:0;white-space:inherit;overflow:visible}.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,.markdown-body pre.vega>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,.markdown-body pre.vega>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%;object-fit:contain;z-index:0}.youtube img{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%;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}#MathJax_Message{z-index:1000!important}.ui-infobar{position:relative;z-index:2;max-width:760px;margin:25px auto -25px;color:#777}.toc .invisable-node{list-style-type:none}.ui-toc{position:fixed;bottom:20px;z-index:998}.ui-toc.both-mode{margin-left:8px}.ui-toc.both-mode .ui-toc-label{height:40px;padding:10px 4px;border-top-left-radius:0;border-bottom-left-radius:0}.ui-toc-label{background-color:#e6e6e6;border:none;color:#868686;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:20px;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{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica Neue,Helvetica,Roboto,Arial,sans-serif}html[lang^=ja] .markdown-body{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica Neue,Helvetica,Roboto,Arial,Hiragino Kaku Gothic Pro,ヒラギノ角ゴ Pro W3,Osaka,Meiryo,メイリオ,MS Gothic,ＭＳ\ ゴシック,sans-serif}html[lang=zh-tw] .markdown-body{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica Neue,Helvetica,Roboto,Arial,PingFang TC,Microsoft JhengHei,微軟正黑,sans-serif}html[lang=zh-cn] .markdown-body{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica Neue,Helvetica,Roboto,Arial,PingFang SC,Microsoft YaHei,微软雅黑,sans-serif}html .markdown-body[lang^=ja]{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica Neue,Helvetica,Roboto,Arial,Hiragino Kaku Gothic Pro,ヒラギノ角ゴ Pro W3,Osaka,Meiryo,メイリオ,MS Gothic,ＭＳ\ ゴシック,sans-serif}html .markdown-body[lang=zh-tw]{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica Neue,Helvetica,Roboto,Arial,PingFang TC,Microsoft JhengHei,微軟正黑,sans-serif}html .markdown-body[lang=zh-cn]{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica Neue,Helvetica,Roboto,Arial,PingFang SC,Microsoft YaHei,微软雅黑,sans-serif}html[lang^=ja] .ui-toc-dropdown{font-family:Source Sans Pro,Helvetica,Arial,Meiryo UI,MS PGothic,ＭＳ\ Ｐゴシック,sans-serif}html[lang=zh-tw] .ui-toc-dropdown{font-family:Source Sans Pro,Helvetica,Arial,Microsoft JhengHei UI,微軟正黑UI,sans-serif}html[lang=zh-cn] .ui-toc-dropdown{font-family:Source Sans Pro,Helvetica,Arial,Microsoft YaHei UI,微软雅黑UI,sans-serif}html .ui-toc-dropdown[lang^=ja]{font-family:Source Sans Pro,Helvetica,Arial,Meiryo UI,MS PGothic,ＭＳ\ Ｐゴシック,sans-serif}html .ui-toc-dropdown[lang=zh-tw]{font-family:Source Sans Pro,Helvetica,Arial,Microsoft JhengHei UI,微軟正黑UI,sans-serif}html .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:50%;margin-top:2px;margin-bottom:2px;margin-right:5px;background-position:50%;background-repeat:no-repeat;background-size:cover}.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}.ui-more-info{color:#888;cursor:pointer;vertical-align:middle}.ui-more-info .fa{font-size:16px}.ui-connectedGithub,.ui-published-note{color:#888}.ui-connectedGithub{line-height:23px;white-space:nowrap}.ui-connectedGithub a.file-path{color:#888;text-decoration:none;padding-left:22px}.ui-connectedGithub a.file-path:active,.ui-connectedGithub a.file-path:hover{color:#888;text-decoration:underline}.ui-connectedGithub .fa{font-size:20px}.ui-published-note .fa{font-size:20px;vertical-align:top}.unselectable{-webkit-user-select:none;-o-user-select:none;user-select:none}.selectable{-webkit-user-select:text;-o-user-select:text;user-select:text}@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;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}.site-ui-font{font-family:Source Sans Pro,Helvetica,Arial,sans-serif}html[lang^=ja] .site-ui-font{font-family:Source Sans Pro,Helvetica,Arial,Hiragino Kaku Gothic Pro,ヒラギノ角ゴ Pro W3,Osaka,Meiryo,メイリオ,MS Gothic,ＭＳ\ ゴシック,sans-serif}html[lang=zh-tw] .site-ui-font{font-family:Source Sans Pro,Helvetica,Arial,PingFang TC,Microsoft JhengHei,微軟正黑,sans-serif}html[lang=zh-cn] .site-ui-font{font-family:Source Sans Pro,Helvetica,Arial,PingFang SC,Microsoft YaHei,微软雅黑,sans-serif}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;letter-spacing:.025em;font-family:Source Sans Pro,Helvetica,Arial,sans-serif}html[lang^=ja] body{font-family:Source Sans Pro,Helvetica,Arial,Hiragino Kaku Gothic Pro,ヒラギノ角ゴ Pro W3,Osaka,Meiryo,メイリオ,MS Gothic,ＭＳ\ ゴシック,sans-serif}html[lang=zh-tw] body{font-family:Source Sans Pro,Helvetica,Arial,PingFang TC,Microsoft JhengHei,微軟正黑,sans-serif}html[lang=zh-cn] body{font-family:Source Sans Pro,Helvetica,Arial,PingFang SC,Microsoft YaHei,微软雅黑,sans-serif}abbr[title]{border-bottom:none;text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted}abbr[data-original-title],abbr[title]{cursor:help}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 comment-enabled" data-hard-breaks="true" style=""><style>
ins { background-color: #A0FFA0 }
s { background-color: #FFA0A0 }
blockquote { color: inherit !important }
</style><table><tbody>
<tr><th>Doc. no.:</th>    <td>P0849R5</td></tr>
<tr><th>Date:</th>        <td>2020-10-30</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="autox-decay-copy-in-the-language" data-id="autox-decay-copy-in-the-language" style=""><a class="anchor hidden-xs" href="#autox-decay-copy-in-the-language" title="autox-decay-copy-in-the-language"><span class="octicon octicon-link"></span></a><span>auto(x): </span><em><span>decay-copy</span></em><span> in the language</span></h1><h2 id="Changes-Since-R4" data-id="Changes-Since-R4" style=""><a class="anchor hidden-xs" href="#Changes-Since-R4" title="Changes-Since-R4"><span class="octicon octicon-link"></span></a><span>Changes Since R4</span></h2><ul>
<li><span>record LWG feedback</span></li>
<li><span>rebase and refine the wording</span></li>
<li><span>demo examples</span></li>
</ul><h2 id="Changes-Since-R3" data-id="Changes-Since-R3" style=""><a class="anchor hidden-xs" href="#Changes-Since-R3" title="Changes-Since-R3"><span class="octicon octicon-link"></span></a><span>Changes Since R3</span></h2><ul>
<li><span>complete library wording</span></li>
</ul><h2 id="Changes-Since-R2" data-id="Changes-Since-R2" style=""><a class="anchor hidden-xs" href="#Changes-Since-R2" title="Changes-Since-R2"><span class="octicon octicon-link"></span></a><span>Changes Since R2</span></h2><ul>
<li><span>dropped </span><code>decltype(auto)(x)</code><span> in comply with EWG’s opinion</span></li>
</ul><h2 id="Changes-Since-R1" data-id="Changes-Since-R1" style=""><a class="anchor hidden-xs" href="#Changes-Since-R1" title="Changes-Since-R1"><span class="octicon octicon-link"></span></a><span>Changes Since R1</span></h2><ul>
<li><span>propose </span><code>decltype(auto)(x)</code><span> as well</span></li>
</ul><h2 id="Changes-Since-R0" data-id="Changes-Since-R0" style=""><a class="anchor hidden-xs" href="#Changes-Since-R0" title="Changes-Since-R0"><span class="octicon octicon-link"></span></a><span>Changes Since R0</span></h2><ul>
<li><span>updated examples</span></li>
<li><span>discussed </span><code>decltype(auto)(x)</code></li>
<li><span>added library wording</span></li>
</ul><h2 id="Introduction" data-id="Introduction" style=""><a class="anchor hidden-xs" href="#Introduction" title="Introduction"><span class="octicon octicon-link"></span></a><span>Introduction</span></h2><p><span>This paper proposes </span><code>auto(x)</code><span> and </span><code>auto{x}</code><span> for casting </span><code>x</code><span> into a prvalue as if passing </span><code>x</code><span> as a function argument by value.  The functionality appears as the </span><em><code>decay-copy</code></em><span> function in the standard for exposition only.</span></p><h2 id="Motivation" data-id="Motivation" style=""><a class="anchor hidden-xs" href="#Motivation" title="Motivation"><span class="octicon octicon-link"></span></a><span>Motivation</span></h2><h3 id="Obtaining-a-prvalue-copy-is-necessary" data-id="Obtaining-a-prvalue-copy-is-necessary" style=""><a class="anchor hidden-xs" href="#Obtaining-a-prvalue-copy-is-necessary" title="Obtaining-a-prvalue-copy-is-necessary"><span class="octicon octicon-link"></span></a><span>Obtaining a prvalue copy is necessary</span></h3><p><span>A generic way to obtain a copy of an object in C++ is </span><code>auto a = x;</code><span> but such a copy is an lvalue.  We could often convey the purpose in code more accurately if we can obtain the copy as a prvalue.  In the following example, let </span><code>Container</code><span> be a concept,</span></p><pre><code class="c++ hljs"><span class="hljs-selector-tag">void</span> <span class="hljs-selector-tag">pop_front_alike</span>(<span class="hljs-selector-tag">Container</span> <span class="hljs-selector-tag">auto</span>&amp; <span class="hljs-selector-tag">x</span>) {
    <span class="hljs-attribute">std</span>::<span class="hljs-built_in">erase</span>(x.begin(), x.<span class="hljs-built_in">end</span>(), <span class="hljs-built_in">auto</span>(x.front()));
}
</code></pre><p><span>If we wrote</span></p><pre><code class="c++ hljs">void pop_front_alike(Container auto&amp; x) {
    auto a = x.front();
    std::erase(x.<span class="hljs-keyword">begin</span>(), x.<span class="hljs-keyword">end</span>(), a);
}
</code></pre><p><span>, questions arise – why this is not equivalent to</span></p><pre><code class="c++ hljs"><span class="hljs-selector-tag">void</span> <span class="hljs-selector-tag">pop_front_alike</span>(<span class="hljs-selector-tag">Container</span> <span class="hljs-selector-tag">auto</span>&amp; <span class="hljs-selector-tag">x</span>) {
    <span class="hljs-attribute">std</span>::<span class="hljs-built_in">erase</span>(x.begin(), x.<span class="hljs-built_in">end</span>(), x.<span class="hljs-built_in">front</span>());
}
</code></pre><p><span>The problem is, the statement to obtain an lvalue copy is a declaration:</span></p><pre><code class="c++ hljs">    <span class="hljs-attribute">auto</span> a = x.front();
</code></pre><p><span>The declaration’s primary purpose is to declare a variable, while the variable being a copy is the declaration’s property.  In contrast, the expression to obtain an rvalue copy is a clear command to perform a copy:</span></p><pre><code class="c++ hljs">    <span class="hljs-selector-tag">auto</span>(<span class="hljs-selector-tag">x</span><span class="hljs-selector-class">.front</span>())
</code></pre><p><span>One might argue that the above is indifferent from</span></p><pre><code class="c++ hljs">    <span class="hljs-selector-tag">T</span>(<span class="hljs-selector-tag">x</span><span class="hljs-selector-class">.front</span>())
</code></pre><p><span>However, there are plenty of situations that the </span><code>T</code><span> is nontrivial to get.  We probably don’t want to write the original example as</span></p><pre><code class="c++ hljs">void pop_front_alike(Container auto&amp; x) {
    using T = std::decay_t&lt;decltype(x.front())&gt;;
    std::erase(x.<span class="hljs-keyword">begin</span>(), x.<span class="hljs-keyword">end</span>(), T(x.front()));
}
</code></pre><h3 id="Obtaining-a-prvalue-copy-with-autox-works-always" data-id="Obtaining-a-prvalue-copy-with-autox-works-always" style=""><a class="anchor hidden-xs" href="#Obtaining-a-prvalue-copy-with-autox-works-always" title="Obtaining-a-prvalue-copy-with-autox-works-always"><span class="octicon octicon-link"></span></a><span>Obtaining a prvalue copy with </span><code>auto(x)</code><span> works always</span></h3><p><span>In standard library specification, we use the following exposition only function to fulfill </span><code>auto(x)</code><span>'s role:</span></p><pre><code class="c++ hljs">template&lt;<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">T</span>&gt;</span>
constexpr decay_t&lt;T&gt; decay_copy(T&amp;&amp; v) noexcept(
    is_nothrow_convertible_v&lt;T, decay_t&lt;T<span class="hljs-meta">&gt;&gt;</span>) {
    return std::forward&lt;T&gt;(v);
}
</code></pre><p><span>This definition involves templates, dependent </span><code>constexpr</code><span>, forwarding reference, </span><code>noexcept</code><span>, and two traits, and still has caveats if people want to use it in practice.  An obvious issue is that </span><code>decay_copy(x.front())</code><span> copies </span><code>x.front()</code><span> even if </span><code>x.front()</code><span> is a prvalue, in other words, a copy.</span></p><p><span>There is a less obvious issue that needs a minimal reproduce:</span></p><pre data-original-title="" title=""><code class="c++ hljs"><span class="hljs-keyword">class</span> <span class="hljs-title">A</span> {
    <span class="hljs-keyword">int</span> x;

<span class="hljs-keyword">public</span>:
    A();

    <span class="hljs-function">auto <span class="hljs-title">run</span>(<span class="hljs-params"></span>) </span>{
        f(A(*<span class="hljs-keyword">this</span>));           <span class="hljs-comment">// ok</span>
        f(auto(*<span class="hljs-keyword">this</span>));        <span class="hljs-comment">// ok as proposed</span>
        f(decay_copy(*<span class="hljs-keyword">this</span>));  <span class="hljs-comment">// ill-formed</span>
    }

<span class="hljs-keyword">protected</span>:
    A(<span class="hljs-keyword">const</span> A&amp;);
};
</code></pre><p><span>The problem is that </span><code>decay_copy</code><span> is nobody’s </span><code>friend</code><span>.  We can use </span><code>A</code><span> directly in this specific example.  However, in a more general setting, where a type has access to a set of type </span><code>T</code><span>'s private or protected copy/move constructors, </span><em><code>decay-copy</code></em><span> an object of </span><code>T</code><span> fails inside that type’s class scope, but </span><code>auto(x)</code><span> continues to work.</span></p><h2 id="Discussion" data-id="Discussion" style=""><a class="anchor hidden-xs" href="#Discussion" title="Discussion"><span class="octicon octicon-link"></span></a><span>Discussion</span></h2><h3 id="autox-is-a-missing-piece" data-id="autox-is-a-missing-piece" style=""><a class="anchor hidden-xs" href="#autox-is-a-missing-piece" title="autox-is-a-missing-piece"><span class="octicon octicon-link"></span></a><code>auto(x)</code><span> is a missing piece</span></h3><p><span>Replacing the </span><code>char</code><span> in </span><code>char('a')</code><span> with </span><code>auto</code><span>, we obtain </span><code>auto('a')</code><span>, which is a function-style cast.  Such a formula also supports </span><em><span>injected-class-names</span></em><span> and class template argument deduction in C++17.  Introducing </span><code>auto(x)</code><span> and </span><code>auto{x}</code><span> significantly improves the language consistency:</span></p><table>
<thead>
<tr>
<th><span>variable definition</span></th>
<th><span>function-style cast</span></th>
<th><span>new expression</span></th>
</tr>
</thead>
<tbody>
<tr>
<td><span>auto v(x);</span></td>
<td><mark><span>auto(x)</span></mark></td>
<td><span>new auto(x)</span></td>
</tr>
<tr>
<td><span>auto v{x};</span></td>
<td><mark><span>auto{x}</span></mark></td>
<td><span>new auto{x}</span></td>
</tr>
<tr>
<td><span>ClassTemplate v(x);</span></td>
<td><span>ClassTemplate(x)</span></td>
<td><span>new ClassTemplate(x)</span></td>
</tr>
<tr>
<td><span>ClassTemplate v{x};</span></td>
<td><span>ClassTemplate{x}</span></td>
<td><span>new ClassTemplate{x}</span></td>
</tr>
</tbody>
</table><p><span>** </span><em><span>The type of </span><code>x</code><span> is a specialization of </span><code>ClassTemplate</code><span>.</span></em></p><p><span>With this proposal, all the cells in the table copy construct form </span><code>x</code><span> (due to CTAD’s default behavior) to obtain lvalues, prvalues, and pointers to objects, categorized by their columns.  Defining </span><code>auto(x)</code><span> as a library</span><sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup><span> facility loses orthogonality.</span></p><p><span>Introducing </span><code>auto(x)</code><span> into the language even improves the library consistency:</span></p><table>
<thead>
<tr>
<th><span>type function style</span></th>
<th><span>expression style</span></th>
</tr>
</thead>
<tbody>
<tr>
<td><span>void_t&lt;decltype(</span><em><span>expr</span></em><span>)&gt;</span></td>
<td><span>decltype(void(</span><em><span>expr</span></em><span>))</span></td>
</tr>
<tr>
<td><span>decay_t&lt;decltype(</span><em><span>expr</span></em><span>)&gt;</span></td>
<td><mark><span>decltype(auto(</span><em><span>expr</span></em><span>))</span></mark></td>
</tr>
</tbody>
</table><h3 id="Do-we-also-miss-decltypeautox" data-id="Do-we-also-miss-decltypeautox" style=""><a class="anchor hidden-xs" href="#Do-we-also-miss-decltypeautox" title="Do-we-also-miss-decltypeautox"><span class="octicon octicon-link"></span></a><span>Do we also miss </span><code>decltype(auto){x}</code><span>?</span></h3><p><code>decltype(auto){arg}</code><span> can forward </span><code>arg</code><span> without computing </span><code>arg</code><span>'s type.  It is equivalent to </span><code>static_cast&lt;decltype(arg)&gt;(arg) </code><span>.  If </span><code>arg</code><span> is a variable of type </span><code>T&amp;&amp;</code><span>, </span><code>arg</code><span> is an lvalue but </span><code>static_cast&lt;T&amp;&amp;&gt;(arg)</code><span> is an xvalue.</span></p><p><span>EWG discussed this idea, disliked its expert-friendly nature, and concluded that adding this facility would cause the teaching effort to add up.</span></p><h3 id="Does-auto-works-in-place-of-decay-copy-in-the-library-specification" data-id="Does-auto-works-in-place-of-decay-copy-in-the-library-specification" style=""><a class="anchor hidden-xs" href="#Does-auto-works-in-place-of-decay-copy-in-the-library-specification" title="Does-auto-works-in-place-of-decay-copy-in-the-library-specification"><span class="octicon octicon-link"></span></a><span>Does </span><code>auto</code><span> works in place of </span><em><code>decay-copy</code></em><span> in the library specification?</span></h3><p><span>Not as a simple find-and-replace, but can be made to improve the quality of the library specification.</span></p><p><span>The background is that, despite being exposition-only, </span><em><code>decay-copy</code></em><span> always materializes its argument and produces a copy. </span><code>auto(expr)</code><span> is a no-op if the </span><code>expr</code><span> is a prvalue.</span></p><p><span>In the library specification where uses </span><em><code>decay-copy</code></em><span>, some do not mean to materialize the expressions; some want a new copy; some do not care. However, with </span><code>auto(x)</code><span> semantics, we should distinguish the different needs and explicitly say so when a copy is needed.</span></p><h2 id="Demo" data-id="Demo" style=""><a class="anchor hidden-xs" href="#Demo" title="Demo"><span class="octicon octicon-link"></span></a><span>Demo</span></h2><p><span>Prevent algorithm from modifying through aliases: </span><a href="https://godbolt.miator.net/z/hhcvbc" target="_blank" rel="noopener"><span>https://godbolt.miator.net/z/hhcvbc</span></a></p><p><span>Using </span><code>auto(x)</code><span> in rvalue fluent interface: </span><a href="https://godbolt.miator.net/z/TY8sxr" target="_blank" rel="noopener"><span>https://godbolt.miator.net/z/TY8sxr</span></a></p><p><span>How </span><code>auto(x)</code><span> assists in defining concepts: </span><a href="https://godbolt.miator.net/z/GTaaeE" target="_blank" rel="noopener"><span>https://godbolt.miator.net/z/GTaaeE</span></a></p><p><span>Compare diagnosis to </span><code>new auto(x)</code><span>: </span><a href="https://godbolt.miator.net/z/Ks43an" target="_blank" rel="noopener"><span>https://godbolt.miator.net/z/Ks43an</span></a></p><h2 id="Wording" data-id="Wording" style=""><a class="anchor hidden-xs" href="#Wording" title="Wording"><span class="octicon octicon-link"></span></a><span>Wording</span></h2><p><span>The wording is relative to N4868.</span></p><h3 id="Part-1" data-id="Part-1" style=""><a class="anchor hidden-xs" href="#Part-1" title="Part-1"><span class="octicon octicon-link"></span></a><span>Part 1</span></h3><p><span>Modify 7.6.1.4 [expr.type.conv]/1 as indicated:</span></p><blockquote>
<p><span>A </span><em><span>simple-type-specifier</span></em><span> (9.2.9.3) or </span><em><span>typename-specifier</span></em><span> (13.8) followed by a parenthesized optional </span><em><span>expression-list</span></em><span> or by a </span><em><span>braced-init-list</span></em><span> (the initializer) constructs a value of the specified type given the initializer. If the type is a placeholder for a deduced class type, it is replaced by the return type of the function selected by</span>
<span>overload resolution for class template deduction (12.4.2.9) for the remainder of this section. </span><ins><span>Otherwise, if the type is </span><code>auto</code><span>, it is replaced by the type deduced for the variable </span><code>x</code><span> in the invented</span>
<span>declaration (</span><a href="http://eel.is/c++draft/dcl.spec.auto" target="_blank" rel="noopener"><span>[dcl.spec.auto]</span></a><span>):</span></ins></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><ins><code><span>auto x </span><em><span>init</span></em><span>;</span></code></ins></p>
<p><ins><span>, where  </span><em><span>init</span></em><span> is the initializer.</span></ins></p>
</blockquote><p><span>Modify 9.2.9.6 [dcl.spec.auto]/5 as indicated:</span></p><blockquote>
<p><span>A placeholder type can also be used in the </span><em><span>type-specifier-seq</span></em><span> in the </span><em><span>new-type-id</span></em><span> or </span><em><span>type-id</span></em><span> of a </span><em><span>new-expression</span></em>
<span>(7.6.2.8) and as a </span><em><span>decl-specifier</span></em><span> of the </span><em><span>parameter-declaration</span></em><span>’s </span><em><span>decl-specifier-seq</span></em><span> in a </span><em><span>template-parameter</span></em>
<span>(13.2).  </span><ins><span>The </span><code>auto</code><span> </span><em><span>type-specifier</span></em><span> can also be used as the </span><em><span>simple-type-specifier</span></em><span> in an explicit type conversion (functional notation) (</span><a href="http://eel.is/c++draft/expr.type.conv" target="_blank" rel="noopener"><span>[expr.type.conv]</span></a><span>).</span></ins></p>
</blockquote><h3 id="Part-2" data-id="Part-2" style=""><a class="anchor hidden-xs" href="#Part-2" title="Part-2"><span class="octicon octicon-link"></span></a><span>Part 2</span></h3><p><span>Modify 24.3.2 [range.access.begin]/2 as indicated:</span></p><blockquote>
<p><span>Given a subexpression </span><code>E</code><span> with type </span><code>T</code><span>, let </span><code>t</code><span> be an lvalue that denotes the reified object for </span><code>E</code><span>. Then:</span></p>
<ul>
<li><span>If </span><code>E</code><span> is an rvalue and </span><code>enable_borrowed_range&lt;remove_cv_t&lt;T&gt;&gt;</code><span> is </span><code>false</code><span>, </span><code>ranges::begin(E)</code><span> is ill-formed.</span></li>
<li><span>Otherwise, if </span><code>T</code><span> is an array type (6.8.3) and </span><code>remove_all_extents_t&lt;T&gt;</code><span> is an incomplete type, </span><code>ranges::begin(E)</code><span> is ill-formed with no diagnostic required.</span></li>
<li><span>Otherwise, if </span><code>T</code><span> is an array type, </span><code>ranges::begin(E)</code><span> is expression-equivalent to </span><code>t + 0</code><span>.</span></li>
<li><span>Otherwise, if </span><s><em><code>decay-copy</code></em></s><ins><code>auto</code></ins><code>(t.begin())</code><span> is a valid expression whose type models </span><code>input_or_output_iterator</code><span>, </span><code>ranges::begin(E)</code><span> is expression-equivalent to </span><s><em><code>decay-copy</code></em></s><ins><code>auto</code></ins><code>(t.begin())</code><span>.</span></li>
<li><span>Otherwise, if </span><code>T</code><span> is a class or enumeration type and </span><s><em><code>decay-copy</code></em></s><ins><code>auto</code></ins><code>(begin(t))</code><span> is a valid expression whose type models </span><code>input_or_output_iterator</code><span> with overload resolution performed in a context in which unqualified lookup for </span><code>begin</code><span> finds only the declarations</span><br>
<span>&nbsp;&nbsp;</span><code><span>void begin(auto&amp;) = delete;</span></code><br>
<span>&nbsp;&nbsp;</span><code><span>void begin(const auto&amp;) = delete;</span></code><br>
<span>then </span><code>ranges::begin(E)</code><span> is expression-equivalent to </span><s><em><code>decay-copy</code></em></s><ins><code>auto</code></ins><code>(begin(t))</code><span> with overload resolution performed in the above context.</span></li>
<li><span>Otherwise, </span><code>ranges::begin(E)</code><span> is ill-formed.</span></li>
</ul>
</blockquote><p><span>Modify 24.3.3 [range.access.end]/2 as indicated:</span></p><blockquote>
<p><span>Given a subexpression </span><code>E</code><span> with type </span><code>T</code><span>, let </span><code>t</code><span> be an lvalue that denotes the reified object for </span><code>E</code><span>. Then:</span></p>
<ul>
<li><span>If </span><code>E</code><span> is an rvalue and </span><code>enable_borrowed_range&lt;remove_cv_t&lt;T&gt;&gt;</code><span> is </span><code>false</code><span>, </span><code>ranges::end(E)</code><span> is ill-formed.</span></li>
<li><span>Otherwise, if </span><code>T</code><span> is an array type (6.8.3) and </span><code>remove_all_extents_t&lt;T&gt;</code><span> is an incomplete type, </span><code>ranges::end(E)</code><span> is ill-formed with no diagnostic required.</span></li>
<li><span>Otherwise, if </span><code>T</code><span> is an array of unknown bound, </span><code>ranges::end(E)</code><span> is ill-formed.</span></li>
<li><span>Otherwise, if </span><code>T</code><span> is an array, </span><code>ranges::end(E)</code><span> is expression-equivalent to </span><code>t + extent_v&lt;T&gt;</code><span>.</span></li>
<li><span>Otherwise, if </span><s><em><code>decay-copy</code></em></s><ins><code>auto</code></ins><code>(t.end())</code><span> is a valid expression whose type models </span><code>sentinel_for&lt;iterator_t&lt;T&gt;&gt;</code><span> then </span><code>ranges::end(E)</code><span> is expression-equivalent to </span><s><em><code>decay-copy</code></em></s><ins><code>auto</code></ins><code>(t.end())</code><span>.</span></li>
<li><span>Otherwise, if </span><code>T</code><span> is a class or enumeration type and </span><s><em><code>decay-copy</code></em></s><ins><code>auto</code></ins><code>(end(t))</code><span> is a valid expression whose type models </span><code>sentinel_for&lt;iterator_t&lt;T&gt;&gt;</code><span> with overload resolution performed in a context in which unqualified lookup for </span><code>end</code><span> finds only the declarations</span><br>
<span>&nbsp;&nbsp;</span><code><span>void end(auto&amp;) = delete;</span></code><br>
<span>&nbsp;&nbsp;</span><code><span>void end(const auto&amp;) = delete;</span></code><br>
<span>then </span><code>ranges::end(E)</code><span> is expression-equivalent to </span><s><em><code>decay-copy</code></em></s><ins><code>auto</code></ins><code>(end(t))</code><span> with overload resolution performed in the above context.</span></li>
<li><span>Otherwise, </span><code>ranges::end(E)</code><span> is ill-formed.</span></li>
</ul>
</blockquote><p><span>Modify 24.3.6 [range.access.rbegin]/2 as indicated:</span></p><blockquote>
<p><span>Given a subexpression </span><code>E</code><span> with type </span><code>T</code><span>, let </span><code>t</code><span> be an lvalue that denotes the reified object for </span><code>E</code><span>. Then:</span></p>
<ul>
<li><span>If </span><code>E</code><span> is an rvalue and </span><code>enable_borrowed_range&lt;remove_cv_t&lt;T&gt;&gt;</code><span> is </span><code>false</code><span>, </span><code>ranges::rbegin(E)</code><span> is ill-formed.</span></li>
<li><span>Otherwise, if </span><code>T</code><span> is an array type (6.8.3) and </span><code>remove_all_extents_t&lt;T&gt;</code><span> is an incomplete type, </span><code>ranges::rbegin(E)</code><span> is ill-formed with no diagnostic required.</span></li>
<li><span>Otherwise, if </span><s><em><code>decay-copy</code></em></s><ins><code>auto</code></ins><code>(t.rbegin())</code><span> is a valid expression whose type models </span><code>input_or_output_iterator</code><span>, </span><code>ranges::rbegin(E)</code><span> is expression-equivalent to </span><s><em><code>decay-copy</code></em></s><ins><code>auto</code></ins><code>(t.rbegin())</code><span>.</span></li>
<li><span>Otherwise, if </span><code>T</code><span> is a class or enumeration type and </span><s><em><code>decay-copy</code></em></s><ins><code>auto</code></ins><code>(rbegin(t))</code><span> is a valid expression whose type models </span><code>input_or_output_iterator</code><span> with overload resolution performed in a context in which unqualified lookup for </span><code>rbegin</code><span> finds only the declarations</span><br>
<span>&nbsp;&nbsp;</span><code><span>void rbegin(auto&amp;) = delete;</span></code><br>
<span>&nbsp;&nbsp;</span><code><span>void rbegin(const auto&amp;) = delete;</span></code><br>
<span>then </span><code>ranges::rbegin(E)</code><span> is expression-equivalent to </span><s><em><code>decay-copy</code></em></s><ins><code>auto</code></ins><code>(rbegin(t))</code><span> with overload resolution performed in the above context.</span></li>
<li><span>[…]</span></li>
</ul>
</blockquote><p><span>Modify 24.3.7 [range.access.rend]/2 as indicated:</span></p><blockquote>
<p><span>Given a subexpression </span><code>E</code><span> with type </span><code>T</code><span>, let </span><code>t</code><span> be an lvalue that denotes the reified object for </span><code>E</code><span>. Then:</span></p>
<ul>
<li><span>If </span><code>E</code><span> is an rvalue and </span><code>enable_borrowed_range&lt;remove_cv_t&lt;T&gt;&gt;</code><span> is </span><code>false</code><span>, </span><code>ranges::rend(E)</code><span> is ill-formed.</span></li>
<li><span>Otherwise, if </span><code>T</code><span> is an array type (6.8.3) and </span><code>remove_all_extents_t&lt;T&gt;</code><span> is an incomplete type, </span><code>ranges::rend(E)</code><span> is ill-formed with no diagnostic required.</span></li>
<li><span>Otherwise, if </span><s><em><code>decay-copy</code></em></s><ins><code>auto</code></ins><code>(t.rend())</code><span> is a valid expression whose type models </span><code>sentinel_for&lt;decltype(ranges::rbegin(E)&gt;</code><span> then </span><code>ranges::rend(E)</code><span> is expression-equivalent to </span><s><em><code>decay-copy</code></em></s><ins><code>auto</code></ins><code>(t.rend())</code><span>.</span></li>
<li><span>Otherwise, if </span><code>T</code><span> is a class or enumeration type and </span><s><em><code>decay-copy</code></em></s><ins><code>auto</code></ins><code>(rend(t))</code><span> is a valid expression whose type models </span><code>sentinel_for&lt;decltype(ranges::rbegin(E)&gt;</code><span> with overload resolution performed in a context in which unqualified lookup for </span><code>rend</code><span> finds only the declarations</span><br>
<span>&nbsp;&nbsp;</span><code><span>void rend(auto&amp;) = delete;</span></code><br>
<span>&nbsp;&nbsp;</span><code><span>void rend(const auto&amp;) = delete;</span></code><br>
<span>then </span><code>ranges::rend(E)</code><span> is expression-equivalent to </span><s><em><code>decay-copy</code></em></s><ins><code>auto</code></ins><code>(rend(t))</code><span> with overload resolution performed in the above context.</span></li>
<li><span>[…]</span></li>
</ul>
</blockquote><p><span>Modify 24.3.10 [range.prim.size]/2 as indicated:</span></p><blockquote>
<p><span>Given a subexpression </span><code>E</code><span> with type </span><code>T</code><span>, let </span><code>t</code><span> be an lvalue that denotes the reified object for </span><code>E</code><span>. Then:</span></p>
<ul>
<li><span>If </span><code>T</code><span> is an array of unknown bound (9.3.4.5), </span><code>ranges::size(E)</code><span> is ill-formed.</span></li>
<li><span>Otherwise, if </span><code>T</code><span> is an array type, </span><code>ranges::size(E)</code><span> is expression-equivalent to </span><s><em><code>decay-copy</code></em></s><ins><code>auto</code></ins><code>(extent_v&lt;T&gt;)</code><span>.</span></li>
<li><span>Otherwise, if </span><code>disable_sized_range&lt;remove_cv_t&lt;T&gt;&gt;</code><span> (24.4.3) is </span><code>false</code><span> and </span><s><em><code>decay-copy</code></em></s><ins><code>auto</code></ins><code>(t.size())</code><span> is a valid expression of integer-like type (23.3.4.4), </span><code>ranges::size(E)</code><span> is expression-equivalent to </span><s><em><code>decay-copy</code></em></s><ins><code>auto</code></ins><code>(t.size())</code><span>.</span></li>
<li><span>Otherwise, if </span><code>T</code><span> is a class or enumeration type, </span><code>disable_sized_range&lt;remove_cv_t&lt;T&gt;&gt;</code><span> is </span><code>false</code><span> and </span><s><em><code>decay-copy</code></em></s><ins><code>auto</code></ins><code>(size(t))</code><span> is a valid expression of integer-like type with overload resolution performed in a context in which unqualified lookup for </span><code>size</code><span> finds only the declarations</span><br>
<span>&nbsp;&nbsp;</span><code><span>void size(auto&amp;) = delete;</span></code><br>
<span>&nbsp;&nbsp;</span><code><span>void size(const auto&amp;) = delete;</span></code><br>
<span>then </span><code>ranges::size(E)</code><span> is expression-equivalent to </span><s><em><code>decay-copy</code></em></s><ins><code>auto</code></ins><code>(size(t))</code><span> with overload resolution performed in the above context.</span></li>
<li><span>[…]</span></li>
</ul>
</blockquote><p><span>Modify 24.3.13 [range.prim.data]/2 as indicated:</span></p><blockquote>
<p><span>Given a subexpression </span><code>E</code><span> with type </span><code>T</code><span>, let </span><code>t</code><span> be an lvalue that denotes the reified object for </span><code>E</code><span>. Then:</span></p>
<ul>
<li><span>If </span><code>E</code><span> is an rvalue and </span><code>enable_borrowed_range&lt;remove_cv_t&lt;T&gt;&gt;</code><span> is </span><code>false</code><span>, </span><code>ranges::data(E)</code><span> is ill-formed.</span></li>
<li><span>Otherwise, if </span><code>T</code><span> is an array type (6.8.3) and </span><code>remove_all_extents_t&lt;T&gt;</code><span> is an incomplete type, </span><code>ranges::data(E)</code><span> is ill-formed with no diagnostic required.</span></li>
<li><span>Otherwise, if </span><s><em><code>decay-copy</code></em></s><ins><code>auto</code></ins><code>(t.data())</code><span> is a valid expression of pointer to object type, </span><code>ranges::data(E)</code><span> is expression-equivalent to </span><s><em><code>decay-copy</code></em></s><ins><code>auto</code></ins><code>(t.data())</code><span>.</span></li>
<li><span>[…]</span></li>
</ul>
</blockquote><p><span>Modify 24.7.4.1 [range.all.general]/2 as indicated:</span></p><blockquote>
<p><span>The name </span><code>views::all</code><span> denotes a range adaptor object (24.7.2). Given a subexpression </span><code>E</code><span>, the expression </span><code>views::all(E)</code><span> is expression-equivalent to:</span></p>
<ul>
<li><code><em><span>decay-copy</span></em><span>(E)</span></code><span> if the </span><s><span>decayed type of </span><code>E</code></s><ins><span>type of </span><code>auto(E)</code></ins><span> models </span><code>view</code><span>.</span></li>
<li><span>Otherwise, </span><code>ref_view{E}</code><span> if that expression is well-formed.</span></li>
<li><span>Otherwise, </span><code>subrange{E}</code><span>.</span></li>
</ul>
</blockquote><div class="alert alert-warning">
<p><em><span>[Drafting note:</span></em>
<span>We could replace this use of </span><code><em><span>decay-copy</span></em><span>(E)</span></code><span> (along with the other two in [range.take] and [range.drop]) with </span><code>auto(identity()(E))</code><span>, but it doesn’t seem to be an improvement.</span>
<em><span>–end note]</span></em></p>
</div><p><span>Modify 32.4.3.3 [thread.thread.constr]/6 as indicated:</span></p><blockquote>
<p><em><span>Effects:</span></em><span> The new thread of execution executes</span></p>
<p><span>&nbsp;&nbsp;</span><code style="white-space: pre-wrap"><span>invoke(</span><s><em><span>decay-copy</span></em></s><ins><span>auto</span></ins><span>(std::forward&lt;F&gt;(f)),</span></code><br>
<span>&nbsp;&nbsp;</span><code style="white-space: pre-wrap"><span>       </span><s><em><span>decay-copy</span></em></s><ins><span>auto</span></ins><span>(std::forward&lt;Args&gt;&gt;(args))…)</span></code></p>
<p><span>with the </span><s><span>calls to </span><em><code>decay-copy</code></em><span> being evaluated</span></s><ins><span>values produced by </span><code>auto</code><span> being materialized (</span><a href="http://eel.is/c++draft/conv#rval" target="_blank" rel="noopener"><span>[conv.rval]</span></a><span>)</span></ins><span> in the constructing thread. Any return value from this invocation is ignored. […]</span></p>
</blockquote><p><span>Modify 32.4.4.2 [thread.jthread.cons]/6 as indicated:</span></p><blockquote>
<p><em><span>Effects:</span></em><span> Initializes </span><code>ssource</code><span>. The new thread of execution executes</span></p>
<p><span>&nbsp;&nbsp;</span><code style="white-space: pre-wrap"><span>invoke(</span><s><em><span>decay-copy</span></em></s><ins><span>auto</span></ins><span>(std::forward&lt;F&gt;(f)), get_stop_token(),</span></code><br>
<span>&nbsp;&nbsp;</span><code style="white-space: pre-wrap"><span>       </span><s><em><span>decay-copy</span></em></s><ins><span>auto</span></ins><span>(std::forward&lt;Args&gt;&gt;(args))…)</span></code></p>
<p><span>if that expression is well-formed, otherwise</span></p>
<p><span>&nbsp;&nbsp;</span><code style="white-space: pre-wrap"><span>invoke(</span><s><em><span>decay-copy</span></em></s><ins><span>auto</span></ins><span>(std::forward&lt;F&gt;(f)),</span></code><br>
<span>&nbsp;&nbsp;</span><code style="white-space: pre-wrap"><span>       </span><s><em><span>decay-copy</span></em></s><ins><span>auto</span></ins><span>(std::forward&lt;Args&gt;&gt;(args))…)</span></code></p>
<p><span>with the </span><s><span>calls to </span><em><code>decay-copy</code></em><span> being evaluated</span></s><ins><span>values produced by </span><code>auto</code><span> being materialized (</span><a href="http://eel.is/c++draft/conv#rval" target="_blank" rel="noopener"><span>[conv.rval]</span></a><span>)</span></ins><span> in the constructing thread. Any return value from this invocation is ignored. […]</span></p>
</blockquote><p><span>Modify 32.9.9 [futures.async]/4 as indicated:</span></p><blockquote>
<p><em><span>Effects:</span></em><span> The first function behaves the same as a call to the second function with a </span><code>policy</code><span> argument of </span><code>launch::async | launch::deferred</code><span> […]:</span></p>
<ul>
<li><span>If </span><code>launch::async</code><span> is set in </span><code>policy</code><span>, calls </span><code><span>invoke(</span><s><em><span>decay-copy</span></em></s><ins><span>auto</span></ins><span>(std::forward&lt;F&gt;(f)), </span><s><em><span>decay-copy</span></em></s><ins><span>auto</span></ins><span>(std::forward&lt;Args&gt;&gt;(args))…)</span></code><span> (20.14.4, 32.4.3.3) as if in a new thread of execution represented by a </span><code>thread</code><span> object with the </span><s><span>calls to </span><em><code>decay-copy</code></em><span> being evaluated</span></s><ins><span>values produced by </span><code>auto</code><span> being materialized (</span><a href="http://eel.is/c++draft/conv#rval" target="_blank" rel="noopener"><span>[conv.rval]</span></a><span>)</span></ins><span> in the thread that called </span><code>async</code><span>. Any return value is stored as the result in the shared state. Any exception propagated from the execution of </span><code><span>invoke(</span><s><em><span>decay-copy</span></em></s><ins><span>auto</span></ins><span>(std::forward&lt;F&gt;(f)), </span><s><em><span>decay-copy</span></em></s><ins><span>auto</span></ins><span>(std::forward&lt;Args&gt;&gt;(args))…)</span></code><span> is stored as the exceptional result in the shared state. The </span><code>thread</code><span> object is stored in the shared state and affects the behavior of any asynchronous return objects that</span>
<span>reference that state.</span></li>
<li><span>If </span><code>launch::deferred</code><span> is set in </span><code>policy</code><span>, stores </span><s><em><code>decay-copy</code></em></s><ins><code>auto</code></ins><code>(std::forward&lt;F&gt;(f))</code><span> and </span><s><em><code>decay-copy</code></em></s><ins><code>auto</code></ins><code>(std::forward&lt;Args&gt;(args))...</code><span> in the shared state. These copies of </span><code>f</code><span> and </span><code>args</code><span> constitute a deferred function. Invocation of the deferred function evaluates </span><code>invoke(std::move(g), std::move(xyz))</code><span> where </span><code>g</code><span> is the stored value of </span><s><em><code>decay-copy</code></em></s><ins><code>auto</code></ins><code>(std::forward&lt;F&gt;(f))</code><span> and </span><code>xyz</code><span> is the stored copy of </span><s><em><code>decay-copy</code></em></s><ins><code>auto</code></ins><code>(std::forward&lt;Args&gt;(args))...</code><span>. Any return value is stored as</span>
<span>the result in the shared state. Any exception propagated from the execution of the deferred</span>
<span>function is stored as the exceptional result in the shared state. […]</span></li>
</ul>
</blockquote><p><span>Modify 17.11.6 [cmp.alg] as indicated:</span></p><div class="alert alert-warning">
<p><em><span>[Drafting note:</span></em>
<span>This section proposes a resolution for LWG 3491</span><sup class="footnote-ref"><a href="#fn2" id="fnref2">[2]</a></sup><span>.</span>
<em><span>–end note]</span></em></p>
</div><blockquote>
<p><span>The name </span><code>strong_order</code><span> denotes a customization point object (16.3.3.3.6). Given subexpressions </span><code>E</code><span> and </span><code>F</code><span>, the expression </span><code>strong_order(E, F)</code><span> is expression-equivalent (3.21) to the following:</span></p>
<ul>
<li><span>If </span><s><span>the decayed types of </span><code>E</code><span> and </span><code>F</code><span> differ</span></s><ins><code>auto(E)</code><span> and </span><code>auto(F)</code><span> are of different types</span></ins><span>, </span><code>strong_order(E, F)</code><span> is ill-formed.</span></li>
<li><span>Otherwise, […]</span></li>
<li><span>Otherwise, </span><ins><span>let </span><code>T</code><span> be </span><code>decltype(auto(E))</code><span>.</span></ins><span> </span><s><span>if the decayed type T of E</span></s><ins><span>If </span><code>T</code></ins><span> is a floating-point type, yields a value of type </span><code>strong_ordering</code><span> that is consistent with the ordering observed by </span><code>T</code><span>'s comparison operators, and if </span><code>numeric_limits&lt;T&gt;::is_iec559</code><span> is </span><code>true</code><span>, is additionally consistent with the </span><code>totalOrder</code><span> operation as specified in ISO/IEC/IEEE 60559.</span></li>
<li><span>[…]</span></li>
</ul>
<p><span>The name </span><code>weak_order</code><span> denotes a customization point object (16.3.3.3.6). Given subexpressions </span><code>E</code><span> and </span><code>F</code><span>, the expression </span><code>weak_order(E, F)</code><span> is expression-equivalent (3.21) to the following:</span></p>
<ul>
<li><span>If </span><s><span>the decayed types of E and F differ</span></s><ins><code>auto(E)</code><span> and </span><code>auto(F)</code><span> are of different types</span></ins><span>, </span><code>weak_order(E, F)</code><span> is ill-formed.</span></li>
<li><span>Otherwise, […]</span></li>
<li><span>Otherwise, </span><ins><span>let </span><code>T</code><span> be </span><code>decltype(auto(E))</code><span>.</span></ins><span> </span><s><span>if the decayed type T of E</span></s><ins><span>If </span><code>T</code></ins><span> is a floating-point type, yields a value of type </span><code>weak_ordering</code><span> that is consistent with the ordering observed by </span><code>T</code><span>'s comparison operators and </span><code>strong_order</code><span>, and</span>
<span>if </span><code>numeric_limits&lt;T&gt;::is_iec559</code><span> is </span><code>true</code><span>, […]</span></li>
</ul>
<p><span>The name </span><code>partial_order</code><span> denotes a customization point object (16.3.3.3.6). Given subexpressions </span><code>E</code><span> and </span><code>F</code><span>, the expression </span><code>partial_order(E, F)</code><span> is expression-equivalent (3.21) to the following:</span></p>
<ul>
<li><span>If </span><s><span>the decayed types of E and F differ</span></s><ins><code>auto(E)</code><span> and </span><code>auto(F)</code><span> are of different types</span></ins><span>, </span><code>partial_order(E, F)</code><span> is ill-formed.</span></li>
<li><span>[…]</span></li>
</ul>
<p><span>The name </span><code>compare_strong_order_fallback</code><span> denotes a customization point object (16.3.3.3.6). Given subexpressions </span><code>E</code><span> and </span><code>F</code><span>, the expression </span><code>compare_strong_order_fallback(E, F)</code><span> is expression-equivalent (3.21) to the following:</span></p>
<ul>
<li><span>If </span><s><span>the decayed types of E and F differ</span></s><ins><code>auto(E)</code><span> and </span><code>auto(F)</code><span> are of different types</span></ins><span>, </span><code>compare_strong_order_fallback(E, F)</code><span> is ill-formed.</span></li>
<li><span>[…]</span></li>
</ul>
<p><span>The name </span><code>compare_weak_order_fallback</code><span> denotes a customization point object (16.3.3.3.6). Given subexpressions </span><code>E</code><span> and </span><code>F</code><span>, the expression </span><code>compare_weak_order_fallback(E, F)</code><span> is expression-equivalent (3.21) to the following:</span></p>
<ul>
<li><span>If </span><s><span>the decayed types of E and F differ</span></s><ins><code>auto(E)</code><span> and </span><code>auto(F)</code><span> are of different types</span></ins><span>, </span><code>compare_weak_order_fallback(E, F)</code><span> is ill-formed.</span></li>
<li><span>[…]</span></li>
</ul>
<p><span>The name </span><code>compare_partial_order_fallback</code><span> denotes a customization point object (16.3.3.3.6). Given subexpressions </span><code>E</code><span> and </span><code>F</code><span>, the expression </span><code>compare_partial_order_fallback(E, F)</code><span> is expression-equivalent (3.21) to the following:</span></p>
<ul>
<li><span>If </span><s><span>the decayed types of E and F differ</span></s><ins><code>auto(E)</code><span> and </span><code>auto(F)</code><span> are of different types</span></ins><span>, </span><code>compare_partial_order_fallback(E, F)</code><span> is ill-formed.</span></li>
<li><span>[…]</span></li>
</ul>
</blockquote><h2 id="Acknowledgments" data-id="Acknowledgments" style=""><a class="anchor hidden-xs" href="#Acknowledgments" title="Acknowledgments"><span class="octicon octicon-link"></span></a><span>Acknowledgments</span></h2><p><span>Thank Alisdair Meredith, Arthur O’Dwyer, and Billy O’Neal for providing examples and feedback for this paper.  Thank James Touton for presenting the paper and bringing it forward.  Thank Jens Maurer and Casey Carter for reviewing the wording.</span></p><h2 id="References" data-id="References" style=""><a class="anchor hidden-xs" href="#References" title="References"><span class="octicon octicon-link"></span></a><span>References</span></h2><hr class="footnotes-sep"><section class="footnotes">
<ol class="footnotes-list">
<li id="fn1" class="footnote-item"><p><span>Krügler, Daniel. P0758R0 </span><em><span>Implicit conversion traits and utility functions</span></em><span>.</span>
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0758r0.html" target="_blank" rel="noopener"><span>http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0758r0.html</span></a> <a href="#fnref1" class="footnote-backref">↩︎</a></p>
</li>
<li id="fn2" class="footnote-item"><p><span>Meredith, Alisdair. LWG 3491 </span><em><span>What is a “decayed type?”</span></em>
<a href="https://cplusplus.github.io/LWG/issue3491" target="_blank" rel="noopener"><span>https://cplusplus.github.io/LWG/issue3491</span></a> <a href="#fnref2" 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="#autox-decay-copy-in-the-language" title="auto(x): decay-copy in the language">auto(x): decay-copy in the language</a><ul class="nav">
<li><a href="#Changes-Since-R4" title="Changes Since R4">Changes Since R4</a></li>
<li><a href="#Changes-Since-R3" title="Changes Since R3">Changes Since R3</a></li>
<li><a href="#Changes-Since-R2" title="Changes Since R2">Changes Since R2</a></li>
<li><a href="#Changes-Since-R1" title="Changes Since R1">Changes Since R1</a></li>
<li><a href="#Changes-Since-R0" title="Changes Since R0">Changes Since R0</a></li>
<li><a href="#Introduction" title="Introduction">Introduction</a></li>
<li><a href="#Motivation" title="Motivation">Motivation</a><ul class="nav">
<li><a href="#Obtaining-a-prvalue-copy-is-necessary" title="Obtaining a prvalue copy is necessary">Obtaining a prvalue copy is necessary</a></li>
<li><a href="#Obtaining-a-prvalue-copy-with-autox-works-always" title="Obtaining a prvalue copy with auto(x) works always">Obtaining a prvalue copy with auto(x) works always</a></li>
</ul>
</li>
<li><a href="#Discussion" title="Discussion">Discussion</a><ul class="nav">
<li><a href="#autox-is-a-missing-piece" title="auto(x) is a missing piece">auto(x) is a missing piece</a></li>
<li><a href="#Do-we-also-miss-decltypeautox" title="Do we also miss decltype(auto){x}?">Do we also miss decltype(auto){x}?</a></li>
<li><a href="#Does-auto-works-in-place-of-decay-copy-in-the-library-specification" title="Does auto works in place of decay-copy in the library specification?">Does auto works in place of decay-copy in the library specification?</a></li>
</ul>
</li>
<li><a href="#Demo" title="Demo">Demo</a></li>
<li><a href="#Wording" title="Wording">Wording</a><ul class="nav">
<li><a href="#Part-1" title="Part 1">Part 1</a></li>
<li><a href="#Part-2" title="Part 2">Part 2</a></li>
</ul>
</li>
<li><a href="#Acknowledgments" title="Acknowledgments">Acknowledgments</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;" null null>
        <div class="toc"><ul class="nav">
<li class=""><a href="#autox-decay-copy-in-the-language" title="auto(x): decay-copy in the language">auto(x): decay-copy in the language</a><ul class="nav">
<li class=""><a href="#Changes-Since-R4" title="Changes Since R4">Changes Since R4</a></li>
<li class=""><a href="#Changes-Since-R3" title="Changes Since R3">Changes Since R3</a></li>
<li class=""><a href="#Changes-Since-R2" title="Changes Since R2">Changes Since R2</a></li>
<li class=""><a href="#Changes-Since-R1" title="Changes Since R1">Changes Since R1</a></li>
<li class=""><a href="#Changes-Since-R0" title="Changes Since R0">Changes Since R0</a></li>
<li class=""><a href="#Introduction" title="Introduction">Introduction</a></li>
<li class=""><a href="#Motivation" title="Motivation">Motivation</a><ul class="nav">
<li class=""><a href="#Obtaining-a-prvalue-copy-is-necessary" title="Obtaining a prvalue copy is necessary">Obtaining a prvalue copy is necessary</a></li>
<li class=""><a href="#Obtaining-a-prvalue-copy-with-autox-works-always" title="Obtaining a prvalue copy with auto(x) works always">Obtaining a prvalue copy with auto(x) works always</a></li>
</ul>
</li>
<li class=""><a href="#Discussion" title="Discussion">Discussion</a><ul class="nav">
<li><a href="#autox-is-a-missing-piece" title="auto(x) is a missing piece">auto(x) is a missing piece</a></li>
<li class=""><a href="#Do-we-also-miss-decltypeautox" title="Do we also miss decltype(auto){x}?">Do we also miss decltype(auto){x}?</a></li>
<li class=""><a href="#Does-auto-works-in-place-of-decay-copy-in-the-library-specification" title="Does auto works in place of decay-copy in the library specification?">Does auto works in place of decay-copy in the library specification?</a></li>
</ul>
</li>
<li class=""><a href="#Demo" title="Demo">Demo</a></li>
<li class=""><a href="#Wording" title="Wording">Wording</a><ul class="nav">
<li class=""><a href="#Part-1" title="Part 1">Part 1</a></li>
<li class=""><a href="#Part-2" title="Part 2">Part 2</a></li>
</ul>
</li>
<li><a href="#Acknowledgments" title="Acknowledgments">Acknowledgments</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>
