<!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>
        Bind front and back to NTTP callables - 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>
        @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{background:#fff;color:#333;display:block;overflow-x:auto;padding:.5em}.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{background-color:#eaffea;color:#55a532}.hljs-deletion{background-color:#ffecec;color:#bd2c00}.hljs-link{text-decoration:underline}.markdown-body{word-wrap:break-word;font-size:16px;line-height:1.5}.markdown-body:after,.markdown-body:before{content:"";display:table}.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;line-height:1;margin-left:-20px;padding-right:4px}.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-bottom:16px;margin-top:0}.markdown-body hr{background-color:#e7e7e7;border:0;height:.25em;margin:24px 0;padding:0}.markdown-body blockquote{border-left:.25em solid #ddd;color:#777;font-size:16px;padding:0 1em}.markdown-body blockquote>:first-child{margin-top:0}.markdown-body blockquote>:last-child{margin-bottom:0}.markdown-body kbd,.popover kbd{background-color:#fcfcfc;border:1px solid;border-color:#ccc #ccc #bbb;border-radius:3px;box-shadow:inset 0 -1px 0 #bbb;color:#555;display:inline-block;font-size:11px;line-height:10px;padding:3px 5px;vertical-align:middle}.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{font-weight:600;line-height:1.25;margin-bottom:16px;margin-top:24px}.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{border-bottom:1px solid #eee;padding-bottom:.3em}.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{color:#777;font-size:.85em}.markdown-body ol,.markdown-body ul{padding-left:2em}.markdown-body ol.no-list,.markdown-body ul.no-list{list-style-type:none;padding:0}.markdown-body ol ol,.markdown-body ol ul,.markdown-body ul ol,.markdown-body ul ul{margin-bottom:0;margin-top:0}.markdown-body li>p{margin-top:16px}.markdown-body li+li{padding-top:.25em}.markdown-body dl{padding:0}.markdown-body dl dt{font-size:1em;font-style:italic;font-weight:700;margin-top:16px;padding:0}.markdown-body dl dd{margin-bottom:16px;padding:0 16px}.markdown-body table{display:block;overflow:auto;width:100%;word-break:normal;word-break:keep-all}.markdown-body table th{font-weight:700}.markdown-body table td,.markdown-body table th{border:1px solid #ddd;padding:6px 13px}.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{background-color:#fff;box-sizing:initial;max-width:100%}.markdown-body img[align=right]{padding-left:20px}.markdown-body img[align=left]{padding-right:20px}.markdown-body .emoji{background-color:initial;max-width:none;vertical-align:text-top}.markdown-body span.frame{display:block;overflow:hidden}.markdown-body span.frame>span{border:1px solid #ddd;display:block;float:left;margin:13px 0 0;overflow:hidden;padding:7px;width:auto}.markdown-body span.frame span img{display:block;float:left}.markdown-body span.frame span span{clear:both;color:#333;display:block;padding:5px 0 0}.markdown-body span.align-center{clear:both;display:block;overflow:hidden}.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{clear:both;display:block;overflow:hidden}.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{background-color:#0000000a;border-radius:3px;font-size:85%;margin:0;padding:.2em 0}.markdown-body code:after,.markdown-body code:before,.markdown-body tt:after,.markdown-body tt:before{content:"\00a0";letter-spacing:-.2em}.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{background:#0000;border:0;font-size:100%;margin:0;padding:0;white-space:pre;word-break:normal}.markdown-body .highlight{margin-bottom:16px}.markdown-body .highlight pre{margin-bottom:0;word-break:normal}.markdown-body .highlight pre,.markdown-body pre{background-color:#f7f7f7;border-radius:3px;font-size:85%;line-height:1.45;overflow:auto;padding:16px}.markdown-body pre code,.markdown-body pre tt{word-wrap:normal;background-color:initial;border:0;display:inline;line-height:inherit;margin:0;max-width:auto;overflow:visible;padding: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{font-size:12px;line-height:1;overflow:hidden;padding:5px;text-align:left;white-space:nowrap}.markdown-body .csv-data .blob-line-num{background:#fff;border:0;padding:10px 8px 9px;text-align:right}.markdown-body .csv-data tr{border-top:0}.markdown-body .csv-data th{background:#f8f8f8;border-top:0;font-weight:700}.news .alert .markdown-body blockquote{border:0;padding:0 0 0 40px}.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{cursor:default!important;float:left;margin:.31em 0 .2em -1.3em!important;vertical-align:middle}.markdown-body{max-width:758px;overflow:visible!important;padding-bottom:40px;padding-top:40px;position:relative}.markdown-body.next-editor{overflow-x:hidden!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;user-select:none}.markdown-body pre code .gutter.linenumber{border-right:3px solid #6ce26c!important;box-sizing:initial;color:#afafaf!important;cursor:default;display:inline-block;min-width:20px;padding:0 8px 0 0;position:relative;text-align:right;z-index:4}.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-bottom:none;border-left:none;border-top:none}.markdown-body .gist .line-data{border:none}.markdown-body .gist table{border-collapse:inherit!important;border-spacing:0}.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{margin-bottom:unset;overflow: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:last-child{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{background-color:inherit;border-radius:0;overflow:visible;text-align:center;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,.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{height:100%;max-width:100%}.markdown-body pre>code.wrap{word-wrap:break-word;white-space:pre-wrap;white-space:-moz-pre-wrap;white-space:-pre-wrap;white-space:-o-pre-wrap}.markdown-body .alert>p:last-child,.markdown-body .alert>ul:last-child{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{background-color:#000;background-position:50%;background-repeat:no-repeat;background-size:contain;cursor:pointer;display:table;overflow:hidden;text-align:center}.vimeo,.youtube{position:relative;width:100%}.youtube{padding-bottom:56.25%}.vimeo img{object-fit:contain;width:100%;z-index:0}.youtube img{object-fit:cover;z-index:0}.vimeo iframe,.youtube iframe,.youtube img{height:100%;left:0;position:absolute;top:0;width:100%}.vimeo iframe,.youtube iframe{vertical-align:middle;z-index:1}.vimeo .icon,.youtube .icon{color:#fff;height:auto;left:50%;opacity:.3;position:absolute;top:50%;transform:translate(-50%,-50%);transition:opacity .2s;width:auto;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{bottom:0;height:100%;left:0;position:absolute;right:0;top:0;width:100%}.figma{display:table;padding-bottom:56.25%;position:relative;width:100%}.figma iframe{border:1px solid #eee;bottom:0;height:100%;left:0;position:absolute;right:0;top:0;width:100%}.markmap-container{height:300px}.markmap-container>svg{height:100%;width:100%}.MJX_Assistive_MathML{display:none}#MathJax_Message{z-index:1000!important}.ui-infobar{color:#777;margin:25px auto -25px;max-width:760px;position:relative;z-index:2}.toc .invisable-node{list-style-type:none}.ui-toc{bottom:20px;position:fixed;z-index:998}.ui-toc.both-mode{margin-left:8px}.ui-toc.both-mode .ui-toc-label{border-bottom-left-radius:0;border-top-left-radius:0;height:40px;padding:10px 4px}.ui-toc-label{background-color:#e6e6e6;border:none;color:#868686;transition:opacity .2s}.ui-toc .open .ui-toc-label{color:#fff;opacity:1;transition:opacity .2s}.ui-toc-label:focus{background-color:#ccc;color:#000;opacity:.3}.ui-toc-label:hover{background-color:#ccc;opacity:1;transition:opacity .2s}.ui-toc-dropdown{margin-bottom:20px;margin-top:20px;max-height:70vh;max-width:45vw;overflow:auto;padding-left:10px;padding-right:10px;text-align:inherit;width:25vw}.ui-toc-dropdown>.toc{max-height:calc(70vh - 100px);overflow:auto}.ui-toc-dropdown[dir=rtl] .nav{letter-spacing:.0029em;padding-right:0}.ui-toc-dropdown a{overflow:hidden;text-overflow:ellipsis;white-space:pre}.ui-toc-dropdown .nav>li>a{color:#767676;display:block;font-size:13px;font-weight:500;padding:4px 20px}.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{background-color:initial;border-left:1px solid #000;color:#000;padding-left:19px;text-decoration:none}.ui-toc-dropdown[dir=rtl] .nav>li>a:focus,.ui-toc-dropdown[dir=rtl] .nav>li>a:hover{border-left:none;border-right:1px solid #000;padding-right:19px}.ui-toc-dropdown .nav>.active:focus>a,.ui-toc-dropdown .nav>.active:hover>a,.ui-toc-dropdown .nav>.active>a{background-color:initial;border-left:2px solid #000;color:#000;font-weight:700;padding-left:18px}.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{border-left:none;border-right:2px solid #000;padding-right:18px}.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{font-size:12px;font-weight:400;padding-bottom:1px;padding-left:30px;padding-top:1px}.ui-toc-dropdown[dir=rtl] .nav .nav>li>a{padding-right:30px}.ui-toc-dropdown .nav .nav>li>ul>li>a{font-size:12px;font-weight:400;padding-bottom:1px;padding-left:40px;padding-top:1px}.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{font-weight:500;padding-left:28px}.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{font-weight:500;padding-left:38px}.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,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol}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,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol}html[lang=zh-tw] .markdown-body{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica Neue,Helvetica,Roboto,Arial,PingFang TC,Microsoft JhengHei,微軟正黑,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol}html[lang=zh-cn] .markdown-body{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica Neue,Helvetica,Roboto,Arial,PingFang SC,Microsoft YaHei,微软雅黑,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol}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,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol}html .markdown-body[lang=zh-tw]{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica Neue,Helvetica,Roboto,Arial,PingFang TC,Microsoft JhengHei,微軟正黑,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol}html .markdown-body[lang=zh-cn]{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica Neue,Helvetica,Roboto,Arial,PingFang SC,Microsoft YaHei,微软雅黑,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol}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{max-height:70vh;max-width:15vw;overflow:auto;position:fixed;top:0}.back-to-top,.expand-toggle,.go-to-bottom{color:#999;display:block;font-size:12px;font-weight:500;margin-left:10px;margin-top:10px;padding:4px 10px}.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{background-position:50%;background-repeat:no-repeat;background-size:cover;border-radius:50%;display:block;height:20px;margin-bottom:2px;margin-right:5px;margin-top:2px;width:20px}.ui-user-icon.small{display:inline-block;height:18px;margin:0 0 .2em;vertical-align:middle;width:18px}.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;padding-left:22px;text-decoration:none}.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}.inline-spoiler-section{cursor:pointer}.inline-spoiler-section .spoiler-text{background-color:#333;border-radius:2px}.inline-spoiler-section .spoiler-text>*{opacity:0}.inline-spoiler-section .spoiler-img{filter:blur(10px)}.inline-spoiler-section.raw{background-color:#333;border-radius:2px}.inline-spoiler-section.raw>*{opacity:0}.inline-spoiler-section.unveil{cursor:auto}.inline-spoiler-section.unveil .spoiler-text{background-color:#3333331a}.inline-spoiler-section.unveil .spoiler-text>*{opacity:1}.inline-spoiler-section.unveil .spoiler-img{filter:none}@media print{blockquote,div,img,pre,table{page-break-inside:avoid!important}a[href]:after{font-size:12px!important}}.markdown-body.slides{color:#222;position:relative;z-index:1}.markdown-body.slides:before{background-color:currentColor;bottom:0;box-shadow:0 0 0 50vw;content:"";display:block;left:0;position:absolute;right:0;top:0;z-index:-1}.markdown-body.slides section[data-markdown]{background-color:#fff;margin-bottom:1.5em;position:relative;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{left:1em;max-height:100%;overflow:hidden;position:absolute;right:1em;top:50%;transform:translateY(-50%)}.markdown-body.slides section[data-markdown]>ul{display:inline-block}.markdown-body.slides>section>section+section:after{border:3px solid #777;content:"";height:1.5em;position:absolute;right:1em;top:-1.5em}.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;-webkit-overflow-scrolling:touch;font-family:Source Sans Pro,Helvetica,Arial,sans-serif;letter-spacing:.025em}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}svg{text-shadow:none}
    </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>
ins { background-color: #CCFFCC }
s { background-color: #FFCACA }
blockquote { color: inherit !important }
table.no-alt tr:nth-child(2n) { background-color: inherit }
.godbolt {
    background-size: contain;
    background-repeat: no-repeat;
    background-position-y: center;
    background-image: url("data:image/x-icon;base64,AAABAAEAQEAAAAEAIAAoQgAAFgAAACgAAABAAAAAgAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAEAAAABAAAAAQAAAAMAAAAEAAAABAAAAAUAAAAGAAAABgAAAAUAAAAEAAAABAAAAAMAAAACAAAAAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAACAAAAAwAAAAUAAAAGAAAACAAAAAkAAAALAAAADAAAAAwAAAALAAAACgAAAAgAAAAGAAAABAAAAAMAAAACAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAwAAAAUAAAAIAAAADAAAAA8AAAASAAAAFQAAABYAAAAWAAAAFAAAABMAAAAPAAAADAAAAAgAAAAFAAAAAwAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA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AAwAAAAMAAAACwAAAAoAAAAIAAAABgAAAAUAAAADAAAAAgAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAEAAAABAAAAAgAAAAIAAAADAAAABAAAAAUAAAAGAAAABgAAAAUAAAAFAAAABAAAAAMAAAACAAAAAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAEAAAABAAAAAQAAAAEAAAACAAAAAgAAAAIAAAADAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////////////////////////////////////////////////////////////////////+B/////////wD/////////AH////////4Af////////gA////////8AB/v////4eAAB4f////AAAAAA////4AAAAAB////AAAAAAD///4AAAAAAH///gAB/8AAf///AAf/8AD///8AH//4AP///4A///4B////gH///wH///+A////Af///wH///+A////A8AAA/////4DwAAD/////gfAAAP////4B+AAA////8AH////////wAf////////AB+AAP////8AHwAAf////wAfAAB/////AB8AAH////8AH////////wAf////////wB+AAA/////4HwAAD/////gPAAAP/////A8AAA/////8B////gP///4D///+A////gH///wH///+AP//+Af///4Af//wA////AA//8AD///4AA//AAH///gAAAAAAf///AAAAAAD///+AAAAAAf///8AAAAAD////4eAAB4f////3+AAf7//////+AH////////4Af////////gB/////////AP////////+A////////////////////////////////////////////////////////////////////8=")
}
</style><table><tbody>
<tr><th>Doc. no.:</th>    <td>P2714R1</td></tr>
<tr><th>Date:</th>        <td>2023-6-16</td></tr>
<tr><th>Audience:</th>    <td>LWG</td></tr>
<tr><th>Reply-to:</th>    <td>Zhihao Yuan &lt;zy@miator.net&gt;<br>Tomasz Kamiński &lt;tomaszkam@gmail.com&gt;</td></tr>
</tbody></table><h1 id="Bind-front-and-back-to-NTTP-callables" data-id="Bind-front-and-back-to-NTTP-callables"><a class="anchor hidden-xs" href="#Bind-front-and-back-to-NTTP-callables" title="Bind-front-and-back-to-NTTP-callables"><span class="octicon octicon-link"></span></a><span>Bind front and back to NTTP callables</span></h1><p><span class="toc"><ul>
<li><a href="#Bind-front-and-back-to-NTTP-callables" title="Bind front and back to NTTP callables">Bind front and back to NTTP callables</a><ul>
<li><a href="#0-Changes-Since-R0" title="0. Changes Since R0">0. Changes Since R0</a></li>
<li><a href="#1-Abstract" title="1. Abstract">1. Abstract</a></li>
<li><a href="#2-Motivation" title="2. Motivation">2. Motivation</a></li>
<li><a href="#3-Discussion" title="3. Discussion">3. Discussion</a><ul>
<li><a href="#31-Why-not-use-a-lambda" title="3.1 Why not use a lambda?">3.1 Why not use a lambda?</a></li>
<li><a href="#32-Should-stdbind-take-an-NTTP" title="3.2 Should std::bind take an NTTP?">3.2 Should std::bind take an NTTP?</a></li>
<li><a href="#33-Should-stdnot_fn-take-an-NTTP" title="3.3 Should std::not_fn take an NTTP?">3.3 Should std::not_fn take an NTTP?</a></li>
</ul>
</li>
<li><a href="#4-Design-Decisions" title="4. Design Decisions">4. Design Decisions</a><ul>
<li><a href="#41-Extend-the-overload-sets" title="4.1 Extend the overload sets">4.1 Extend the overload sets</a></li>
<li><a href="#42-Reject-targets-of-null-pointers-at-compile-time" title="4.2 Reject targets of null pointers at compile-time">4.2 Reject targets of null pointers at compile-time</a></li>
</ul>
</li>
<li><a href="#5-Wording" title="5. Wording">5. Wording</a><ul>
<li><a href="#51-Feature-test-macro" title="5.1 Feature test macro">5.1 Feature test macro</a></li>
</ul>
</li>
<li><a href="#6-Implementation-Experience" title="6. Implementation Experience">6. Implementation Experience</a></li>
<li><a href="#7-References" title="7. References">7. References</a></li>
</ul>
</li>
</ul>
</span></p><h2 id="0-Changes-Since-R0" data-id="0-Changes-Since-R0"><a class="anchor hidden-xs" href="#0-Changes-Since-R0" title="0-Changes-Since-R0"><span class="octicon octicon-link"></span></a><span>0. Changes Since R0</span></h2><ul>
<li><span>refine wording</span></li>
</ul><h2 id="1-Abstract" data-id="1-Abstract"><a class="anchor hidden-xs" href="#1-Abstract" title="1-Abstract"><span class="octicon octicon-link"></span></a><span>1. Abstract</span></h2><p><span>Users of </span><code>std::bind_front</code><span> and </span><code>std::bind_back</code><span> pay what they don’t use when binding arguments to functions, member functions, and sometimes customization point objects. The paper proposes to allow passing callable objects as arguments for non-type template parameters in </span><code>bind_front</code><span> and </span><code>bind_back</code><span> to guarantee zero cost in those use cases. The paper also applies the same technique to </span><code>std::not_fn</code><span>.</span></p><h2 id="2-Motivation" data-id="2-Motivation"><a class="anchor hidden-xs" href="#2-Motivation" title="2-Motivation"><span class="octicon octicon-link"></span></a><span>2. Motivation</span></h2><p><span>The need for partial function application</span><sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup><span> is ubiquitous. Consider the following example modified from Qt 5:</span></p><table class="no-alt"><tbody>
<tr><th>C++20</th><td>
<pre><code class="cpp hljs"><span class="token function">connect</span><span class="token punctuation">(</span>sender<span class="token punctuation">,</span> <span class="token operator">&amp;</span>Sender<span class="token double-colon punctuation">::</span>valueChanged<span class="token punctuation">,</span>
        std<span class="token double-colon punctuation">::</span><span class="token function">bind_front</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>Receiver<span class="token double-colon punctuation">::</span>updateValue<span class="token punctuation">,</span> receiver<span class="token punctuation">,</span> <span class="token string">"Value"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre>
</td></tr>
<tr><th>
<p><mark><span>P2714</span></mark></p>
</th>
<td>
<pre><code class="cpp hljs"><span class="token function">connect</span><span class="token punctuation">(</span>sender<span class="token punctuation">,</span> <span class="token operator">&amp;</span>Sender<span class="token double-colon punctuation">::</span>valueChanged<span class="token punctuation">,</span>
        std<span class="token double-colon punctuation">::</span><span class="token generic-function"><span class="token function">bind_front</span><span class="token generic class-name"><span class="token operator">&lt;</span><span class="token operator">&amp;</span>Receiver<span class="token double-colon punctuation">::</span>updateValue<span class="token operator">&gt;</span></span></span><span class="token punctuation">(</span>receiver<span class="token punctuation">,</span> <span class="token string">"Value"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre>
</td></tr>
</tbody></table><p><span>This paper proposes new overloads to </span><code>bind_front</code><span> and </span><code>bind_back</code><span> that move the binding target to template parameters for the following needs.</span></p><dl>
<dt><span>Reduce the cost of binding arguments to functions and member functions</span></dt>
<dd>
<p><span>Typically, binding arguments to a function using C++20 </span><code>std::bind_front</code><span> requires storing a function pointer along with the arguments, even though the language knows precisely which function to call without a need to dereference the pointer.</span></p>
<pre><code class="cpp hljs"><span class="token keyword">auto</span> fn <span class="token operator">=</span> std<span class="token double-colon punctuation">::</span><span class="token function">bind_front</span><span class="token punctuation">(</span>update_cb<span class="token punctuation">,</span> receiver<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">static_assert</span><span class="token punctuation">(</span><span class="token keyword">sizeof</span><span class="token punctuation">(</span>fn<span class="token punctuation">)</span> <span class="token operator">&gt;</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>receiver<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token keyword">auto</span> meth <span class="token operator">=</span> std<span class="token double-colon punctuation">::</span><span class="token function">bind_front</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>Receiver<span class="token double-colon punctuation">::</span>updateValue<span class="token punctuation">,</span> receiver<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">static_assert</span><span class="token punctuation">(</span><span class="token keyword">sizeof</span><span class="token punctuation">(</span>meth<span class="token punctuation">)</span> <span class="token operator">&gt;</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>receiver<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre>
</dd>
<dd>
<p><span>Similarly, binding arguments to a member function often requires more storage and easily exceeds type-erased callback (such as </span><code>std::function</code><span>)'s SBO buffer capacity. But again, the compiler knows this call pattern at compile-time.</span></p>
</dd>
<dd>
<p><span>The call wrapper objects created by </span><code>bind_front</code><span> (and </span><code>bind_back</code><span>) are of unspecified types that are not meant to be assignable. In other words, the design consideration to support replacing the value of the object “of the same type” at run-time doesn’t exist. We, as users, don’t want to pay performance and space costs for something we don’t want to use and can’t use.</span></p>
</dd>
<dt><span>Simplify implementation and debug codegen</span></dt>
<dd>
<p><span>Captureless lambda gain traction as first-class functions that are safe to use and come with better defaults, which fall into the category of callables of empty classes. Ordinary users would expect binding arguments to empty objects to be indifferent from adding data members to an empty class.</span></p>
</dd>
<dd>
<pre><code class="cpp hljs"><span class="token keyword">auto</span> captureless <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">(</span>FILE <span class="token operator">*</span><span class="token punctuation">,</span> <span class="token keyword">void</span> <span class="token operator">*</span><span class="token punctuation">,</span> size_t<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token keyword">static_assert</span><span class="token punctuation">(</span><span class="token keyword">sizeof</span><span class="token punctuation">(</span>std<span class="token double-colon punctuation">::</span><span class="token function">bind_front</span><span class="token punctuation">(</span>captureless<span class="token punctuation">,</span> <span class="token constant">stdin</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span><span class="token constant">stdin</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre>
</dd>
<dd>
<p><span>But what cost implementations to give this guarantee in </span><code>bind_front</code><span>? Here is a breakdown:</span></p>
</dd>
<dd>
  <table>
      <tbody>
          <tr>
              <th>Impl.</th> <th>Layout</th>
          </tr>
          <tr>
              <th>libc++</th>
              <td>
<pre><code class="cpp hljs">tuple<span class="token operator">&lt;</span>Target<span class="token punctuation">,</span> BoundArgs<span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token operator">&gt;</span> state_entities<span class="token punctuation">;</span>
</code></pre>
  </td>
          </tr>
          <tr>
              <th>MS STL</th>
              <td>
<pre><code class="cpp hljs">_Compressed_pair<span class="token operator">&lt;</span>Target<span class="token punctuation">,</span> tuple<span class="token operator">&lt;</span>BoundArgs<span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token operator">&gt;&gt;</span> state_entities<span class="token punctuation">;</span>
</code></pre>
  </td>
          </tr>
          <tr>
              <th>libstdc++</th>
              <td>
<pre><code class="cpp hljs"><span class="token punctuation">[</span><span class="token punctuation">[</span>no_unique_address<span class="token punctuation">]</span><span class="token punctuation">]</span> Target target<span class="token punctuation">;</span>
tuple<span class="token operator">&lt;</span>BoundArgs<span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token operator">&gt;</span> bound_args<span class="token punctuation">;</span>
</code></pre>
  </td>
          </tr>
          <tr>
              <th><mark>P2714</mark>†</th>
              <td>
<pre><code class="cpp hljs"><span class="token punctuation">[</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span> <span class="token function">bound_args</span><span class="token punctuation">(</span>args<span class="token punctuation">)</span><span class="token punctuation">]</span>  <span class="token comment">// lambda captures</span>
</code></pre>
  </td>
          </tr>
      </tbody>
  </table>
</dd>
<dd>
<p><sup><span>†</span></sup><em><span>A sample implementation can be found at the </span><a href="#6-Implementation-Experience"><span>end of the article</span></a><span>.</span></em></p>
</dd>
<dd>
<p><span>By not storing the call targets, this guarantee is by construction rather than a choice of QoI. Suppose an implementation takes a further step to lower </span><code>std::forward</code><span>, </span><code>std::forward_like</code><span>, and </span><code>std::invoke</code><span> as if they were intrinsics.</span><sup class="footnote-ref"><a href="#fn2" id="fnref2">[2]</a></sup><span> There will be no intermediate layers to bloat debug information when accessing these binders’ state entities.</span></p>
</dd>
<dt><span>Improve the readability of expressions that use </span><code>bind_front</code><span> and </span><code>bind_back</code></dt>
<dd>
<p><span>The </span><code>invoke</code><span>-like call expressions such as </span><code>invoke(func, a, b, ...)</code><span> are becoming conventional in C++. However, unless you’re a Lisp fan, you may still find that </span><code>func(a, b, ...)</code><span> is the “right” way and </span><code>bind_front&lt;func&gt;(a, b)</code><span> to be more natural. The latter form encodes necessary information for a casual reader to distinguish between the target and the bound arguments.</span></p>
</dd>
<dd>
<p><span>Such a visual distinction matters equally well to </span><code>bind_back&lt;func&gt;(a, b)</code><span>, as </span><code>bind_back(func, a, b)</code><span> has an implied “insertion point” for the actual arguments to the call wrapper.</span></p>
</dd>
</dl><h2 id="3-Discussion" data-id="3-Discussion"><a class="anchor hidden-xs" href="#3-Discussion" title="3-Discussion"><span class="octicon octicon-link"></span></a><span>3. Discussion</span></h2><h3 id="31-Why-not-use-a-lambda" data-id="31-Why-not-use-a-lambda"><a class="anchor hidden-xs" href="#31-Why-not-use-a-lambda" title="31-Why-not-use-a-lambda"><span class="octicon octicon-link"></span></a><span>3.1 Why not use a lambda?</span></h3><p><span>The question is probably not asking, “why not use a lambda in C++23,” since today’s lambda does not propagate </span><code>noexcept</code><span> and constraints, nor forwards captures and arguments easily. Assume that we will have a “perfect lambda” in C++26, where applying ‘⤷’ in front of a parameter forwards the argument and laying ‘⤷’ in front of a capture forwards the member using closure’s value category. </span><code>&amp;...</code><span> is a parameter index pack that expands to </span><code>&amp;1</code><span>, </span><code>&amp;2</code><span>, … So this will allow you to write</span></p><pre><code class="cpp hljs"><span class="token punctuation">[</span><span class="token operator">=</span><span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token function">do_work</span><span class="token punctuation">(</span>⤷bnd1<span class="token punctuation">,</span> ⤷bnd2<span class="token punctuation">,</span> ⤷<span class="token operator">&amp;</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">)</span><span class="token punctuation">]</span>
</code></pre><p><span>instead of</span></p><pre><code class="cpp hljs"><span class="token generic-function"><span class="token function">bind_front</span><span class="token generic class-name"><span class="token operator">&lt;</span>do_work<span class="token operator">&gt;</span></span></span><span class="token punctuation">(</span>bnd1<span class="token punctuation">,</span> bnd2<span class="token punctuation">)</span>
</code></pre><p><span>Will I choose the “perfect lambda” instead? Maybe not. Not because the “perfect lambda” is not terse enough. The difference is every symbol in the </span><code>bind_front</code><span> expression is about </span><strong><span>why</span></strong><span> the call wrapper is needed here in the code, while every token in the “perfect lambda” is to explain </span><strong><span>how</span></strong><span> this is done. Partial application is an established idea; people will keep picking up </span><a href="https://docs.python.org/3/library/functools.html#functools.partial" target="_blank" rel="noopener"><code>functools.partial</code></a><span>, although Python’s lambda is sufficiently clean and complete.</span></p><h3 id="32-Should-stdbind-take-an-NTTP" data-id="32-Should-stdbind-take-an-NTTP"><a class="anchor hidden-xs" href="#32-Should-stdbind-take-an-NTTP" title="32-Should-stdbind-take-an-NTTP"><span class="octicon octicon-link"></span></a><span>3.2 Should </span><code>std::bind</code><span> take an NTTP?</span></h3><p><span>Compared to the later added </span><code>std::bind_front</code><span> and </span><code>std::bind_back</code><span>, </span><code>std::bind</code><span> is sub-optimal, and I do not want to encourage its uses. It is too sparse to find a use of </span><code>std::bind</code><span> that actually bound something but cannot be replaced by </span><code>bind_front</code><span> and </span><code>bind_back</code><span>. The unique value of </span><code>std::bind</code><span> comes from its capability of reordering arguments. Being said that, it is likely to be a lower-hanging fruit if we want to introduce a terse lambda that uses parameter indices.</span><sup class="footnote-ref"><a href="#fn3" id="fnref3">[3]</a></sup></p><h3 id="33-Should-stdnot_fn-take-an-NTTP" data-id="33-Should-stdnot_fn-take-an-NTTP"><a class="anchor hidden-xs" href="#33-Should-stdnot_fn-take-an-NTTP" title="33-Should-stdnot_fn-take-an-NTTP"><span class="octicon octicon-link"></span></a><span>3.3 Should </span><code>std::not_fn</code><span> take an NTTP?</span></h3><p><span>A callback may want to negate its boolean result before being type-erased, and introducing </span><code>not_fn&lt;f&gt;()</code><span> seems to be an intuitive answer. But is that the only answer?</span></p><p><span>It’s not hard to implement </span><code>not_fn</code><span> in a way such that the value of </span><code>not_fn(f)</code><span> is of a structural type if </span><code>f</code><span> is of a structural type. Therefore, if you demand a combination of partial application and negation whose call pattern is known at compile-time, you can use </span><code>bind_front&lt;not_fn(f)&gt;(a, b)</code><span>.</span></p><p><span>This can turn into a hostile workaround if I ask users to write </span><code>bind_front&lt;not_fn(f)&gt;()</code><span> when only negation is wanted; </span><code>not_fn&lt;f&gt;()</code><span> expresses the original intention directly.</span></p><table>
<thead>
<tr>
<th><span>Partial</span></th>
<th><span>C++20</span></th>
<th><mark><span>P2714</span></mark></th>
</tr>
</thead>
<tbody>
<tr>
<td><span>Y</span></td>
<td><code>bind_front(not_fn(f), a, b)</code></td>
<td><code>bind_front&lt;not_fn&lt;f&gt;()&gt;(a, b)</code></td>
</tr>
<tr>
<td><span>N</span></td>
<td><code>not_fn(f)</code></td>
<td><code>not_fn&lt;f&gt;()</code></td>
</tr>
</tbody>
</table><p><span>It also raises the question of whether we need an </span><code>fn&lt;f&gt;()</code><span> that encapsulates the </span><code>f</code><span>’s call pattern without negation. It can be deemed an NTTP version of </span><code>std::mem_fn</code><span>, except for not being limited to member pointers.</span></p><p><span>The paper proposes </span><code>not_fn&lt;f&gt;()</code><span>. Whether to require </span><em><span>perfect forward call wrappers</span></em><span> to propagate the structural property when all of their state entities are of structural types deserves a paper on its own, especially when a </span><a href="https://github.com/cplusplus/CWG/issues/15" target="_blank" rel="noopener"><span>core issue</span></a><span> is about to get involved.</span></p><h2 id="4-Design-Decisions" data-id="4-Design-Decisions"><a class="anchor hidden-xs" href="#4-Design-Decisions" title="4-Design-Decisions"><span class="octicon octicon-link"></span></a><span>4. Design Decisions</span></h2><h3 id="41-Extend-the-overload-sets" data-id="41-Extend-the-overload-sets"><a class="anchor hidden-xs" href="#41-Extend-the-overload-sets" title="41-Extend-the-overload-sets"><span class="octicon octicon-link"></span></a><span>4.1 Extend the overload sets</span></h3><p><span>Doing so allows the new APIs to reuse the existing names, </span><code>bind_front</code><span> and </span><code>bind_back</code><span>, enabling the users who are already familiar with these names to make a small change and see benefits.</span></p><p><span>As a design alternative, it was suggested that adding </span><code>operator()</code><span> to </span><code>std::nontype</code><sup class="footnote-ref"><a href="#fn4" id="fnref4">[4]</a></sup><span> can give a similar outcome:</span></p><table class="no-alt"><tbody>
<tr><th>
<p><mark><span>alt.</span></mark></p>
</th><td>
<pre><code class="cpp hljs"><span class="token function">connect</span><span class="token punctuation">(</span>sender<span class="token punctuation">,</span> <span class="token operator">&amp;</span>Sender<span class="token double-colon punctuation">::</span>valueChanged<span class="token punctuation">,</span>
        std<span class="token double-colon punctuation">::</span><span class="token function">bind_front</span><span class="token punctuation">(</span>std<span class="token double-colon punctuation">::</span>nontype<span class="token operator">&lt;</span><span class="token operator">&amp;</span>Receiver<span class="token double-colon punctuation">::</span>updateValue<span class="token operator">&gt;</span><span class="token punctuation">,</span>
                        receiver<span class="token punctuation">,</span> <span class="token string">"Value"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre>
</td></tr>
<tr><th>
<p><span>P2714</span></p>
</th>
<td>
<pre><code class="cpp hljs"><span class="token function">connect</span><span class="token punctuation">(</span>sender<span class="token punctuation">,</span> <span class="token operator">&amp;</span>Sender<span class="token double-colon punctuation">::</span>valueChanged<span class="token punctuation">,</span>
        std<span class="token double-colon punctuation">::</span><span class="token generic-function"><span class="token function">bind_front</span><span class="token generic class-name"><span class="token operator">&lt;</span><span class="token operator">&amp;</span>Receiver<span class="token double-colon punctuation">::</span>updateValue<span class="token operator">&gt;</span></span></span><span class="token punctuation">(</span>receiver<span class="token punctuation">,</span> <span class="token string">"Value"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre>
</td></tr>
</tbody></table><p><span>The soundness behind the suggestion was that all vendors‡ had implemented EBO in </span><code>bind_front</code><span>; that is to say, the specializations of </span><code>nontype_t</code><span> could be optimized without effort. However, as shown at the </span><a href="#2-Motivation"><span>beginning of the article</span></a><span>, “no effort” means a lot of effort – to generate code and debug information. Though an implementation can create overloads to treat </span><code>nontype_t&lt;f&gt;</code><span> differently, the users get the same thing, only with a convoluted spelling.</span></p><p><span>The design decision extends to </span><code>not_fn</code><span> as well. </span><code>std::not_fn</code><span> is a function template, meaning the same name cannot be redeclared as a variable. Unsurprisingly, keeping users’ familiarity with the existing name outweighs the benefit of saving a pair of parentheses.</span></p><p><sup><span>‡</span></sup><em><span>Except for libstdc++ until GCC 13. See </span><ruby><a href="https://godbolt.org/z/aee1P35b4" target="_blank" rel="noopener"><span class="godbolt"><span> </span></span><span>aee1P35b4</span></a><rt><span>Compiler Explorer</span></rt></ruby><span>.</span></em></p><h3 id="42-Reject-targets-of-null-pointers-at-compile-time" data-id="42-Reject-targets-of-null-pointers-at-compile-time"><a class="anchor hidden-xs" href="#42-Reject-targets-of-null-pointers-at-compile-time" title="42-Reject-targets-of-null-pointers-at-compile-time"><span class="octicon octicon-link"></span></a><span>4.2 Reject targets of null pointers at compile-time</span></h3><p><span>You won’t get a null pointer to function or a null pointer to member via a function-to-pointer conversion or an </span><code>&amp;</code><span> operator in this language. Still, the targets of these types may be computed at compile-time:</span></p><pre><code class="cpp hljs"><span class="token comment">// error: static_assert failed: 'f != nullptr'</span>
std<span class="token double-colon punctuation">::</span>bind_front<span class="token operator">&lt;</span>tbl<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token string">"nonexistent-callback"</span><span class="token punctuation">)</span><span class="token operator">&gt;</span><span class="token punctuation">(</span>a<span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre><p><span>The new overloads have such information ahead of time and can easily diagnose it. </span><code>function_ref</code><span>’s constructor that initializes from </span><code>nontype&lt;f&gt;</code><span> applies the identical practice.</span></p><h2 id="5-Wording" data-id="5-Wording"><a class="anchor hidden-xs" href="#5-Wording" title="5-Wording"><span class="octicon octicon-link"></span></a><span>5. Wording</span></h2><p><span>The wording is relative to </span><a href="https://wg21.link/N4950" target="_blank" rel="noopener"><span>N4950</span></a><span>.</span></p><p><span>Append the following to </span><a href="http://www.eelis.net/c++draft/func.bind.partial" target="_blank" rel="noopener"><span>[func.bind.partial]</span></a><span>, function templates </span><code>bind_front</code><span> and </span><code>bind_back</code><span>:</span></p><div class="alert alert-success">
<pre>template&lt;auto f, class... Args&gt;
  constexpr <i>unspecified</i> bind_front(Args&amp;&amp;... args);
template&lt;auto f, class... Args&gt;
  constexpr <i>unspecified</i> bind_back(Args&amp;&amp;... args);
</pre>
<p><span>Within this subclause:</span></p>
<ul>
<li><code>F</code><span> is the type of </span><code>f</code><span>,</span></li>
<li><code>g</code><span> is a value of the result of a </span><code>bind_front</code><span> or </span><code>bind_back</code><span> invocation,</span></li>
<li><code>BoundArgs</code><span> is a pack that denotes </span><code>decay_t&lt;Args&gt;...</code><span>,</span></li>
<li><code>bound_args</code><span> is a pack of bound argument entities of </span><code>g</code><span> (</span><a href="http://www.eelis.net/c++draft/func.def" target="_blank" rel="noopener"><span>[func.def]</span></a><span>) of types </span><code>BoundArgs...</code><span>, direct-non-list-initialized with </span><code>std::forward&lt;Args&gt;(args)...</code><span>, respectively, and</span></li>
<li><code>call_args</code><span> is an argument pack used in a function call expression (</span><a href="http://www.eelis.net/c++draft/expr.call" target="_blank" rel="noopener"><span>[expr.call]</span></a><span>) of </span><code>g</code><span>.</span></li>
</ul>
<p><em><span>Mandates:</span></em></p>
<ul>
<li><code>(is_constructible_v&lt;BoundArgs, Args&gt; &amp;&amp; ...)</code><span> is </span><code>true</code><span>, and</span></li>
<li><code>(is_move_constructible_v&lt;BoundArgs&gt; &amp;&amp; ...)</code><span> is </span><code>true</code><span>, and</span></li>
<li><span>if </span><code>is_pointer_v&lt;F&gt; || is_member_pointer_v&lt;F&gt;</code><span> is </span><code>true</code><span>, then </span><code>f != nullptr</code><span> is </span><code>true</code><span>.</span></li>
</ul>
<p><em><span>Preconditions:</span></em>
<span>For each</span>
<code>T</code><em><sub><span>i</span></sub></em>
<span>in </span><code>BoundArgs</code><span>,</span>
<code>T</code><em><sub><span>i</span></sub></em>
<span>meets the </span><em><span>Cpp17MoveConstructible</span></em><span> requirements.</span></p>
<p><em><span>Returns:</span></em><span> A perfect forwarding call wrapper (</span><a href="http://www.eelis.net/c++draft/func.require#term.perfect.forwarding.call.wrapper" target="_blank" rel="noopener"><span>[func.require]</span></a><span>) </span><code>g</code><span> that does not have target object, and has the call pattern:</span></p>
<ul>
<li><code>invoke(f, bound_args..., call_args...)</code><span> for a </span><code>bind_front</code><span> invocation, or</span></li>
<li><code>invoke(f, call_args..., bound_args...)</code><span> for a </span><code>bind_back</code><span> invocation.</span></li>
</ul>
<p><em><span>Throws:</span></em><span> Any exception thrown by the initialization of </span><code>bound_args</code><span>.</span></p>
</div><p><span>Append the following to </span><a href="http://www.eelis.net/c++draft/func.not.fn" target="_blank" rel="noopener"><span>[func.not.fn]</span></a><span>, function template </span><code>not_fn</code><span>:</span></p><div class="alert alert-success">
<pre>template&lt;auto f&gt; constexpr <i>unspecified</i> not_fn() noexcept;
</pre>
<p><span>In the text that follows:</span></p>
<ul>
<li><code>F</code><span> is the type of </span><code>f</code><span>,</span></li>
<li><code>g</code><span> is a value of the result of a </span><code>not_fn</code><span> invocation,</span></li>
<li><code>call_args</code><span> is an argument pack used in a function call expression (</span><a href="http://www.eelis.net/c++draft/expr.call" target="_blank" rel="noopener"><span>[expr.call]</span></a><span>) of </span><code>g</code><span>.</span></li>
</ul>
<p><em><span>Mandates:</span></em><span> If </span><code>is_pointer_v&lt;F&gt; || is_member_pointer_v&lt;F&gt;</code><span> is </span><code>true</code><span>, then </span><code>f != nullptr</code><span> is </span><code>true</code><span>.</span></p>
<p><em><span>Returns:</span></em><span> A perfect forwarding call wrapper (</span><a href="http://www.eelis.net/c++draft/func.require#term.perfect.forwarding.call.wrapper" target="_blank" rel="noopener"><span>[func.require]</span></a><span>) </span><code>g</code><span> that does not have state entities, and has the call pattern </span><code>!invoke(f, call_args...)</code><span>.</span></p>
</div><p><span>Add the signatures to </span><a href="https://eel.is/c++draft/functional.syn" target="_blank" rel="noopener"><span>[functional.syn]</span></a><span>, header </span><code>&lt;functional&gt;</code><span> synopsis:</span></p><blockquote>
<p><span>[…]</span></p>
</blockquote><pre>  <i>// [func.not.fn], function template <code>not_fn</code></i>
  template&lt;class F&gt; constexpr <i>unspecified</i> not_fn(F&amp;&amp; f);     <i>// freestanding</i>
<ins>  template&lt;auto f&gt; constexpr <i>unspecified</i> not_fn() noexcept;  <i>// freestanding</i></ins>

  <i>// [func.bind.partial], function templates <code>bind_front</code> and <code>bind_back</code></i>
  template&lt;class F, class... Args&gt;
    constexpr <i>unspecified</i> bind_front(F&amp;&amp;, Args&amp;&amp;...);        <i>// freestanding</i>
  template&lt;class F, class... Args&gt;
    constexpr <i>unspecified</i> bind_back(F&amp;&amp;, Args&amp;&amp;...);         <i>// freestanding</i>

<ins>  template&lt;auto f, class... Args&gt;
    constexpr <i>unspecified</i> bind_front(Args&amp;&amp;...);             <i>// freestanding</i>
  template&lt;auto f, class... Args&gt;
    constexpr <i>unspecified</i> bind_back(Args&amp;&amp;...);              <i>// freestanding</i></ins>
</pre><blockquote>
<p><span>[…]</span></p>
</blockquote><h3 id="51-Feature-test-macro" data-id="51-Feature-test-macro"><a class="anchor hidden-xs" href="#51-Feature-test-macro" title="51-Feature-test-macro"><span class="octicon octicon-link"></span></a><span>5.1 Feature test macro</span></h3><p><span>Update values in </span><a href="https://eel.is/c++draft/version.syn" target="_blank" rel="noopener"><span>[version.syn]</span></a><span>, header </span><code>&lt;version&gt;</code><span> synopsis:</span></p><pre>#define __cpp_lib_bind_back         <s>202202L</s><ins>20XXXXL</ins> <i>// also in &lt;functional&gt;</i>
#define __cpp_lib_bind_front        <s>201907L</s><ins>20XXXXL</ins> <i>// also in &lt;functional&gt;</i>
 [...]
#define __cpp_lib_not_fn            <s>201603L</s><ins>20XXXXL</ins> <i>// also in &lt;functional&gt;</i>
</pre><h2 id="6-Implementation-Experience" data-id="6-Implementation-Experience"><a class="anchor hidden-xs" href="#6-Implementation-Experience" title="6-Implementation-Experience"><span class="octicon octicon-link"></span></a><span>6. Implementation Experience</span></h2><p><span>The snippet below is a full implementation of the proposed </span><code>bind_front</code><span> overload. You can play with this and the rest of the proposal in </span><ruby><a href="https://godbolt.org/z/aGbTe8frj" target="_blank" rel="noopener"><span class="godbolt"><span> </span></span><span>aGbTe8frj</span></a><rt><span>Compiler Explorer</span></rt></ruby><span>.</span></p><pre><code class="cpp hljs"><span class="token keyword">template</span><span class="token operator">&lt;</span><span class="token keyword">class</span> <span class="token class-name">T</span><span class="token punctuation">,</span> <span class="token keyword">class</span> <span class="token class-name">U</span><span class="token operator">&gt;</span>
<span class="token keyword">struct</span> <span class="token class-name">__copy_const</span> <span class="token operator">:</span> <span class="token base-clause"><span class="token class-name">conditional</span><span class="token operator">&lt;</span><span class="token class-name">is_const_v</span><span class="token operator">&lt;</span><span class="token class-name">T</span><span class="token operator">&gt;</span><span class="token punctuation">,</span> <span class="token class-name">U</span> <span class="token keyword">const</span><span class="token punctuation">,</span> <span class="token class-name">U</span><span class="token operator">&gt;</span></span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span>

<span class="token keyword">template</span><span class="token operator">&lt;</span><span class="token keyword">class</span> <span class="token class-name">T</span><span class="token punctuation">,</span> <span class="token keyword">class</span> <span class="token class-name">U</span><span class="token punctuation">,</span>
         <span class="token keyword">class</span> <span class="token class-name">X</span> <span class="token operator">=</span> __copy_const<span class="token operator">&lt;</span>remove_reference_t<span class="token operator">&lt;</span>T<span class="token operator">&gt;</span><span class="token punctuation">,</span> U<span class="token operator">&gt;</span><span class="token double-colon punctuation">::</span>type<span class="token operator">&gt;</span>
<span class="token keyword">struct</span> <span class="token class-name">__copy_value_category</span>
    <span class="token operator">:</span> <span class="token base-clause"><span class="token class-name">conditional</span><span class="token operator">&lt;</span><span class="token class-name">is_lvalue_reference_v</span><span class="token operator">&lt;</span><span class="token class-name">T</span><span class="token operator">&amp;&amp;</span><span class="token operator">&gt;</span><span class="token punctuation">,</span> <span class="token class-name">X</span><span class="token operator">&amp;</span><span class="token punctuation">,</span> <span class="token class-name">X</span><span class="token operator">&amp;&amp;</span><span class="token operator">&gt;</span></span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span>

<span class="token keyword">template</span><span class="token operator">&lt;</span><span class="token keyword">class</span> <span class="token class-name">T</span><span class="token punctuation">,</span> <span class="token keyword">class</span> <span class="token class-name">U</span><span class="token operator">&gt;</span>
<span class="token keyword">struct</span> <span class="token class-name">type_forward_like</span> <span class="token operator">:</span> <span class="token base-clause"><span class="token class-name">__copy_value_category</span><span class="token operator">&lt;</span><span class="token class-name">T</span><span class="token punctuation">,</span> <span class="token class-name">remove_reference_t</span><span class="token operator">&lt;</span><span class="token class-name">U</span><span class="token operator">&gt;&gt;</span></span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span>

<span class="token keyword">template</span><span class="token operator">&lt;</span><span class="token keyword">class</span> <span class="token class-name">T</span><span class="token punctuation">,</span> <span class="token keyword">class</span> <span class="token class-name">U</span><span class="token operator">&gt;</span>
<span class="token keyword">using</span> type_forward_like_t <span class="token operator">=</span> type_forward_like<span class="token operator">&lt;</span>T<span class="token punctuation">,</span> U<span class="token operator">&gt;</span><span class="token double-colon punctuation">::</span>type<span class="token punctuation">;</span>

<span class="token keyword">template</span><span class="token operator">&lt;</span><span class="token keyword">auto</span> f<span class="token punctuation">,</span> <span class="token keyword">class</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span> Args<span class="token operator">&gt;</span>
<span class="token keyword">constexpr</span> <span class="token keyword">auto</span> <span class="token function">bind_front</span><span class="token punctuation">(</span>Args<span class="token operator">&amp;&amp;</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span> args<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">using</span> F <span class="token operator">=</span> <span class="token keyword">decltype</span><span class="token punctuation">(</span>f<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">if</span> <span class="token keyword">constexpr</span> <span class="token punctuation">(</span>is_pointer_v<span class="token operator">&lt;</span>F<span class="token operator">&gt;</span> <span class="token operator">or</span> is_member_pointer_v<span class="token operator">&lt;</span>F<span class="token operator">&gt;</span><span class="token punctuation">)</span>
        <span class="token keyword">static_assert</span><span class="token punctuation">(</span>f <span class="token operator">!=</span> <span class="token keyword">nullptr</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span>
        <span class="token punctuation">[</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span> <span class="token function">bound_args</span><span class="token punctuation">(</span>std<span class="token double-colon punctuation">::</span><span class="token generic-function"><span class="token function">forward</span><span class="token generic class-name"><span class="token operator">&lt;</span>Args<span class="token operator">&gt;</span></span></span><span class="token punctuation">(</span>args<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">]</span><span class="token operator">&lt;</span><span class="token keyword">class</span> <span class="token class-name">Self</span><span class="token punctuation">,</span> <span class="token keyword">class</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span> T<span class="token operator">&gt;</span><span class="token punctuation">(</span>
            <span class="token keyword">this</span> Self<span class="token operator">&amp;&amp;</span><span class="token punctuation">,</span>
            T<span class="token operator">&amp;&amp;</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span> call_args<span class="token punctuation">)</span>
        <span class="token keyword">noexcept</span><span class="token punctuation">(</span>is_nothrow_invocable_v<span class="token operator">&lt;</span>
                 F<span class="token punctuation">,</span> type_forward_like_t<span class="token operator">&lt;</span>Self<span class="token punctuation">,</span> decay_t<span class="token operator">&lt;</span>Args<span class="token operator">&gt;&gt;</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">,</span> T<span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token operator">&gt;</span><span class="token punctuation">)</span>
            <span class="token operator">-&gt;</span> invoke_result_t<span class="token operator">&lt;</span>F<span class="token punctuation">,</span> type_forward_like_t<span class="token operator">&lt;</span>Self<span class="token punctuation">,</span> decay_t<span class="token operator">&lt;</span>Args<span class="token operator">&gt;&gt;</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">,</span>
                               T<span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token operator">&gt;</span> <span class="token punctuation">{</span>
            <span class="token keyword">return</span> std<span class="token double-colon punctuation">::</span><span class="token function">invoke</span><span class="token punctuation">(</span>f<span class="token punctuation">,</span> std<span class="token double-colon punctuation">::</span><span class="token generic-function"><span class="token function">forward_like</span><span class="token generic class-name"><span class="token operator">&lt;</span>Self<span class="token operator">&gt;</span></span></span><span class="token punctuation">(</span>bound_args<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">,</span>
                               std<span class="token double-colon punctuation">::</span><span class="token generic-function"><span class="token function">forward</span><span class="token generic class-name"><span class="token operator">&lt;</span>T<span class="token operator">&gt;</span></span></span><span class="token punctuation">(</span>call_args<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre><h2 id="7-References" data-id="7-References"><a class="anchor hidden-xs" href="#7-References" title="7-References"><span class="octicon octicon-link"></span></a><span>7. References</span></h2><hr class="footnotes-sep"><section class="footnotes">
<ol class="footnotes-list">
<li id="fn1" class="footnote-item"><p><span>Kamiński, Tomasz. P0356R5 </span><em><span>Simplified partial function application</span></em><span>.</span>
<a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0356r5.html" target="_blank" rel="noopener"><span>https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0356r5.html</span></a> <a href="#fnref1" class="footnote-backref">↩︎</a></p>
</li>
<li id="fn2" class="footnote-item"><p><span>DaCamara, Cameron. </span><em><span>Improving the State of Debug Performance in C++</span></em><span>.</span>
<a href="https://devblogs.microsoft.com/cppblog/improving-the-state-of-debug-performance-in-c/" target="_blank" rel="noopener"><span>https://devblogs.microsoft.com/cppblog/improving-the-state-of-debug-performance-in-c/</span></a> <a href="#fnref2" class="footnote-backref">↩︎</a></p>
</li>
<li id="fn3" class="footnote-item"><p><span>Vector of Bool. </span><em><span>A Macro-Based Terse Lambda Expression</span></em><span>.</span>
<a href="https://vector-of-bool.github.io/2021/04/20/terse-lambda-macro.html" target="_blank" rel="noopener"><span>https://vector-of-bool.github.io/2021/04/20/terse-lambda-macro.html</span></a> <a href="#fnref3" class="footnote-backref">↩︎</a></p>
</li>
<li id="fn4" class="footnote-item"><p><span>Romeo, et al. P0792R13 </span><em><span>function_ref: a type-erased callable reference</span></em><span>.</span>
<a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p0792r13.html" target="_blank" rel="noopener"><span>https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p0792r13.html</span></a> <a href="#fnref4" 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="#Bind-front-and-back-to-NTTP-callables" title="Bind front and back to NTTP callables">Bind front and back to NTTP callables</a><ul class="nav">
<li><a href="#0-Changes-Since-R0" title="0. Changes Since R0">0. Changes Since R0</a></li>
<li><a href="#1-Abstract" title="1. Abstract">1. Abstract</a></li>
<li><a href="#2-Motivation" title="2. Motivation">2. Motivation</a></li>
<li><a href="#3-Discussion" title="3. Discussion">3. Discussion</a><ul class="nav">
<li><a href="#31-Why-not-use-a-lambda" title="3.1 Why not use a lambda?">3.1 Why not use a lambda?</a></li>
<li><a href="#32-Should-stdbind-take-an-NTTP" title="3.2 Should std::bind take an NTTP?">3.2 Should std::bind take an NTTP?</a></li>
<li><a href="#33-Should-stdnot_fn-take-an-NTTP" title="3.3 Should std::not_fn take an NTTP?">3.3 Should std::not_fn take an NTTP?</a></li>
</ul>
</li>
<li><a href="#4-Design-Decisions" title="4. Design Decisions">4. Design Decisions</a><ul class="nav">
<li><a href="#41-Extend-the-overload-sets" title="4.1 Extend the overload sets">4.1 Extend the overload sets</a></li>
<li><a href="#42-Reject-targets-of-null-pointers-at-compile-time" title="4.2 Reject targets of null pointers at compile-time">4.2 Reject targets of null pointers at compile-time</a></li>
</ul>
</li>
<li class=""><a href="#5-Wording" title="5. Wording">5. Wording</a><ul class="nav">
<li class=""><a href="#51-Feature-test-macro" title="5.1 Feature test macro">5.1 Feature test macro</a></li>
</ul>
</li>
<li><a href="#6-Implementation-Experience" title="6. Implementation Experience">6. Implementation Experience</a></li>
<li><a href="#7-References" title="7. References">7. 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="#Bind-front-and-back-to-NTTP-callables" title="Bind front and back to NTTP callables">Bind front and back to NTTP callables</a><ul class="nav">
<li><a href="#0-Changes-Since-R0" title="0. Changes Since R0">0. Changes Since R0</a></li>
<li class=""><a href="#1-Abstract" title="1. Abstract">1. Abstract</a></li>
<li class=""><a href="#2-Motivation" title="2. Motivation">2. Motivation</a></li>
<li class=""><a href="#3-Discussion" title="3. Discussion">3. Discussion</a><ul class="nav">
<li class=""><a href="#31-Why-not-use-a-lambda" title="3.1 Why not use a lambda?">3.1 Why not use a lambda?</a></li>
<li><a href="#32-Should-stdbind-take-an-NTTP" title="3.2 Should std::bind take an NTTP?">3.2 Should std::bind take an NTTP?</a></li>
<li class=""><a href="#33-Should-stdnot_fn-take-an-NTTP" title="3.3 Should std::not_fn take an NTTP?">3.3 Should std::not_fn take an NTTP?</a></li>
</ul>
</li>
<li class=""><a href="#4-Design-Decisions" title="4. Design Decisions">4. Design Decisions</a><ul class="nav">
<li class=""><a href="#41-Extend-the-overload-sets" title="4.1 Extend the overload sets">4.1 Extend the overload sets</a></li>
<li class=""><a href="#42-Reject-targets-of-null-pointers-at-compile-time" title="4.2 Reject targets of null pointers at compile-time">4.2 Reject targets of null pointers at compile-time</a></li>
</ul>
</li>
<li class=""><a href="#5-Wording" title="5. Wording">5. Wording</a><ul class="nav">
<li class=""><a href="#51-Feature-test-macro" title="5.1 Feature test macro">5.1 Feature test macro</a></li>
</ul>
</li>
<li><a href="#6-Implementation-Experience" title="6. Implementation Experience">6. Implementation Experience</a></li>
<li><a href="#7-References" title="7. References">7. 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>
