<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
    <meta charset="utf-8">
    <!-- TITLE -->
    <title>is_callable, the missing INVOKE related trait</title>
    <style name="main.css">
        @import url(https://fonts.googleapis.com/css?family=Muli:400,300);
        @import url(https://fonts.googleapis.com/css?family=Share:400,700);
        /* ============================== */
        /* BODY */
        /* ============================== */
        body {
            font-family: 'Muli',arial,sans-serif;
            background-color: #FEFEFE;
            margin: 0;
            padding: 0;
            font-size: 0.875em;
            color: #616161;
        }
        h1, h2, h3, h4, h5, h6 {
            margin-bottom: 0.5em;
            font-family: 'Share';
        }
        .title {
            border-bottom: solid 2px #f5aa10;
        }
        #container {
            margin: 0 auto;
            width: 60%;
            min-width: 640px;
            overflow: auto;
        }
        #main {
            width: 100%;
        }
        a {
            color: #3C6EB4;
            cursor: pointer;
            text-decoration: none;
        }
            a:hover {
                text-decoration: underline;
            }
        /* ============================== */
        /* HEADER */
        /* ============================== */
        #head {
            overflow: auto;
            margin: 40px 0;
        }
            #head div.top {
                font-size: 2.4em;
                margin-right: 80px;
            }
            #head div.bottom {
                height: 38px;
                margin-right: 80px;
            }
            #head .logo {
                vertical-align: bottom;
            }
            #head a.name {
                text-decoration: none;
                color: #555;
                font-weight: bold;
                overflow: auto;
            }
            #head span.slogan {
                color: #CCC;
            }
        /* ============================== */
        /* POST VIEW*/
        /* ============================== */
        article.post {
            margin-bottom: 60px;
            clear: both;
            overflow: auto;
        }
            article.post header.post {
                margin-bottom: 10px;
            }
                article.post header.post h1.title {
                    font-weight: bold;
                    margin: 0;
                }
                    article.post header.post h1.title a {
                        color: inherit;
                        text-decoration: none;
                    }
                article.post header.post div.date {
                    font-size: 0.9em;
                    font-weight: bold;
                    text-align: right;
                    text-transform: uppercase;
                    color: #999;
                }
            article.post .body {
                font-size: 1.2em;
            }
            article.post .console {
                background: url("img/console.png") no-repeat scroll 10px center #F1F1F1;
                display: block;
                line-height: 50px;
                margin: 5px 0;
                padding-left: 60px;
            }
            article.post img:not(.captcha) {
                max-width: 100%;
            }
            article.post blockquote {
                font-size: 1em;
                width: 80%;
                margin-left: 2em;
                padding-left: 0.5em;
                border-left: 2px solid #C3C3C3;
            }
            article.post footer.post {
                clear: both;
                margin-top: 20px;
                text-align: center;
            }
        article pre {
            border: 1px dashed #ccc;
            padding: 1em;
            background: #f4f4f4;
        }
        article.pre, article.code {
            font-family: monospace;
            font-size: 1em;
        }
        /* ============================== */
        /* TABLES */
        /* ============================== */
        table {
            border: 1px solid #999;
        }
            table th, table td {
                background: #f4f4f4;
                padding: 5px 15px;
            }
            table thead {
                border-bottom: 1px solid #999;
            }
            table th {
                font-weight: bold;
                background: #eaeaea;
            }
            table td, table th {
                border-right: 1px solid #999;
            }
    </style>
    <!-- SyntaxHighlighter -->
    <style name="normalize.css">
        article, aside, details, figcaption, figure, footer, header, hgroup, nav, section, summary {
            display: block;
        }
        audio, canvas, video {
            display: inline-block;
        }
            audio:not([controls]) {
                display: none;
                height: 0;
            }
        [hidden] {
            display: none;
        }
        html {
            font-family: sans-serif;
            -webkit-text-size-adjust: 100%;
            -ms-text-size-adjust: 100%;
        }
        a:focus {
            outline: thin dotted;
        }
        a:active, a:hover {
            outline: 0;
        }
        h1 {
            font-size: 2em;
        }
        abbr[title] {
            border-bottom: 1px dotted;
        }
        b, strong {
            font-weight: 700;
        }
        dfn {
            font-style: italic;
        }
        mark {
            background: #ff0;
            color: #000;
        }
        code, kbd, pre, samp {
            font-family: monospace, serif;
            font-size: 1em;
        }
        pre {
            white-space: pre-wrap;
            word-wrap: break-word;
        }
        q {
            quotes: \201C \201D \2018 \2019;
        }
        small {
            font-size: 80%;
        }
        sub, sup {
            font-size: 75%;
            line-height: 0;
            position: relative;
            vertical-align: baseline;
        }
        sup {
            top: -.5em;
        }
        sub {
            bottom: -.25em;
        }
        img {
            border: 0;
        }
        svg:not(:root) {
            overflow: hidden;
        }
        fieldset {
            border: 1px solid silver;
            margin: 0 2px;
            padding: .35em .625em .75em;
        }
        button, input, select, textarea {
            font-family: inherit;
            font-size: 100%;
            margin: 0;
        }
        button, input {
            line-height: normal;
        }
            button, html input[type=button], /* 1 */
            input[type=reset], input[type=submit] {
                -webkit-appearance: button;
                cursor: pointer;
            }
                button[disabled], input[disabled] {
                    cursor: default;
                }
            input[type=checkbox], input[type=radio] {
                box-sizing: border-box;
                padding: 0;
            }
            input[type=search] {
                -webkit-appearance: textfield;
                -moz-box-sizing: content-box;
                -webkit-box-sizing: content-box;
                box-sizing: content-box;
            }
                input[type=search]::-webkit-search-cancel-button, input[type=search]::-webkit-search-decoration {
                    -webkit-appearance: none;
                }
        textarea {
            overflow: auto;
            vertical-align: top;
        }
        table {
            border-collapse: collapse;
            border-spacing: 0;
        }
        body, figure {
            margin: 0;
        }
        legend, button::-moz-focus-inner, input::-moz-focus-inner {
            border: 0;
            padding: 0;
        }
    </style>
    <style name="shCore.css">
        .syntaxhighlighter a,
        .syntaxhighlighter div,
        .syntaxhighlighter code,
        .syntaxhighlighter table,
        .syntaxhighlighter table td,
        .syntaxhighlighter table tr,
        .syntaxhighlighter table tbody,
        .syntaxhighlighter table thead,
        .syntaxhighlighter table caption,
        .syntaxhighlighter textarea {
            -moz-border-radius: 0 0 0 0 !important;
            -webkit-border-radius: 0 0 0 0 !important;
            background: none !important;
            border: 0 !important;
            bottom: auto !important;
            float: none !important;
            height: auto !important;
            left: auto !important;
            line-height: 1.1em !important;
            margin: 0 !important;
            outline: 0 !important;
            overflow: visible !important;
            padding: 0 !important;
            position: static !important;
            right: auto !important;
            text-align: left !important;
            top: auto !important;
            vertical-align: baseline !important;
            width: auto !important;
            box-sizing: content-box !important;
            font-family: monospace !important;
            font-weight: normal !important;
            font-style: normal !important;
            font-size: 1em !important;
            min-height: inherit !important;
            min-height: auto !important;
        }
        .syntaxhighlighter {
            margin: 1em 0 1em 0 !important;
            overflow: auto !important;
            font-size: 1em !important;
        }
            .syntaxhighlighter.source {
                overflow: hidden !important;
            }
            .syntaxhighlighter .bold {
                font-weight: bold !important;
            }
            .syntaxhighlighter .italic {
                font-style: italic !important;
            }
            .syntaxhighlighter .line {
                white-space: pre !important;
            }
            .syntaxhighlighter table {
                width: 100% !important;
            }
                .syntaxhighlighter table caption {
                    text-align: left !important;
                    padding: .5em 0 0.5em 1em !important;
                }
                .syntaxhighlighter table td.code {
                    width: 100% !important;
                }
                    .syntaxhighlighter table td.code .container {
                        position: relative !important;
                    }
                        .syntaxhighlighter table td.code .container textarea {
                            box-sizing: border-box !important;
                            position: absolute !important;
                            left: 0 !important;
                            top: 0 !important;
                            width: 100% !important;
                            height: 100% !important;
                            border: none !important;
                            background: white !important;
                            padding-left: 1em !important;
                            overflow: hidden !important;
                            white-space: pre !important;
                        }
                .syntaxhighlighter table td.gutter .line {
                    text-align: right !important;
                    padding: 0 0.5em 0 1em !important;
                }
                .syntaxhighlighter table td.code .line {
                    padding: 0 1em !important;
                }
            .syntaxhighlighter.nogutter td.code .container textarea, .syntaxhighlighter.nogutter td.code .line {
                padding-left: 0em !important;
            }
            .syntaxhighlighter.show {
                display: block !important;
            }
            .syntaxhighlighter.collapsed table {
                display: none !important;
            }
            .syntaxhighlighter.collapsed .toolbar {
                padding: 0.1em 0.8em 0em 0.8em !important;
                font-size: 1em !important;
                position: static !important;
                width: auto !important;
                height: auto !important;
            }
                .syntaxhighlighter.collapsed .toolbar span {
                    display: inline !important;
                    margin-right: 1em !important;
                }
                    .syntaxhighlighter.collapsed .toolbar span a {
                        padding: 0 !important;
                        display: none !important;
                    }
                        .syntaxhighlighter.collapsed .toolbar span a.expandSource {
                            display: inline !important;
                        }
            .syntaxhighlighter .toolbar {
                position: absolute !important;
                right: 1px !important;
                top: 1px !important;
                width: 11px !important;
                height: 11px !important;
                font-size: 10px !important;
                z-index: 10 !important;
            }
                .syntaxhighlighter .toolbar span.title {
                    display: inline !important;
                }
                .syntaxhighlighter .toolbar a {
                    display: block !important;
                    text-align: center !important;
                    text-decoration: none !important;
                    padding-top: 1px !important;
                }
                    .syntaxhighlighter .toolbar a.expandSource {
                        display: none !important;
                    }
            .syntaxhighlighter.ie {
                font-size: .9em !important;
                padding: 1px 0 1px 0 !important;
            }
                .syntaxhighlighter.ie .toolbar {
                    line-height: 8px !important;
                }
                    .syntaxhighlighter.ie .toolbar a {
                        padding-top: 0px !important;
                    }
            .syntaxhighlighter.printing .line.alt1 .content,
            .syntaxhighlighter.printing .line.alt2 .content,
            .syntaxhighlighter.printing .line.highlighted .number,
            .syntaxhighlighter.printing .line.highlighted.alt1 .content,
            .syntaxhighlighter.printing .line.highlighted.alt2 .content {
                background: none !important;
            }
            .syntaxhighlighter.printing .line .number {
                color: #bbbbbb !important;
            }
            .syntaxhighlighter.printing .line .content {
                color: black !important;
            }
            .syntaxhighlighter.printing .toolbar {
                display: none !important;
            }
            .syntaxhighlighter.printing a {
                text-decoration: none !important;
            }
            .syntaxhighlighter.printing .plain, .syntaxhighlighter.printing .plain a {
                color: black !important;
            }
            .syntaxhighlighter.printing .comments, .syntaxhighlighter.printing .comments a {
                color: #008200 !important;
            }
            .syntaxhighlighter.printing .string, .syntaxhighlighter.printing .string a {
                color: blue !important;
            }
            .syntaxhighlighter.printing .keyword {
                color: #006699 !important;
                font-weight: bold !important;
            }
            .syntaxhighlighter.printing .preprocessor {
                color: gray !important;
            }
            .syntaxhighlighter.printing .variable {
                color: #aa7700 !important;
            }
            .syntaxhighlighter.printing .value {
                color: #009900 !important;
            }
            .syntaxhighlighter.printing .functions {
                color: #ff1493 !important;
            }
            .syntaxhighlighter.printing .constants {
                color: #0066cc !important;
            }
            .syntaxhighlighter.printing .script {
                font-weight: bold !important;
            }
            .syntaxhighlighter.printing .color1, .syntaxhighlighter.printing .color1 a {
                color: gray !important;
            }
            .syntaxhighlighter.printing .color2, .syntaxhighlighter.printing .color2 a {
                color: #ff1493 !important;
            }
            .syntaxhighlighter.printing .color3, .syntaxhighlighter.printing .color3 a {
                color: red !important;
            }
            .syntaxhighlighter.printing .break, .syntaxhighlighter.printing .break a {
                color: black !important;
            }
    </style>
    <style name="shThemeDefault.css">
        .syntaxhighlighter {
            background-color: #f4f4f4 !important;
            border: 1px dashed #ccc;
            padding: 1em;
        }
            .syntaxhighlighter .line.alt1 {
                background-color: #f4f4f4 !important;
            }
            .syntaxhighlighter .line.alt2 {
                background-color: #f4f4f4 !important;
            }
            .syntaxhighlighter .line.highlighted.alt1, .syntaxhighlighter .line.highlighted.alt2 {
                background-color: #e0e0e0 !important;
            }
            .syntaxhighlighter .line.highlighted.number {
                color: black !important;
            }
            .syntaxhighlighter table caption {
                color: black !important;
            }
            .syntaxhighlighter .gutter {
                color: #afafaf !important;
            }
                .syntaxhighlighter .gutter .line {
                    border-right: 3px solid #6ce26c !important;
                }
                    .syntaxhighlighter .gutter .line.highlighted {
                        background-color: #6ce26c !important;
                        color: white !important;
                    }
            .syntaxhighlighter.printing .line .content {
                border: none !important;
            }
            .syntaxhighlighter.collapsed {
                overflow: visible !important;
            }
                .syntaxhighlighter.collapsed .toolbar {
                    color: blue !important;
                    background: #f4f4f4 !important;
                    border: 1px solid #6ce26c !important;
                }
                    .syntaxhighlighter.collapsed .toolbar a {
                        color: blue !important;
                    }
                        .syntaxhighlighter.collapsed .toolbar a:hover {
                            color: red !important;
                        }
            .syntaxhighlighter .toolbar {
                color: #f4f4f4 !important;
                background: #6ce26c !important;
                border: none !important;
            }
                .syntaxhighlighter .toolbar a {
                    color: #f4f4f4 !important;
                }
                    .syntaxhighlighter .toolbar a:hover {
                        color: black !important;
                    }
            .syntaxhighlighter .plain, .syntaxhighlighter .plain a {
                color: black !important;
            }
            .syntaxhighlighter .comments, .syntaxhighlighter .comments a {
                color: #008200 !important;
            }
            .syntaxhighlighter .string, .syntaxhighlighter .string a {
                color: blue !important;
            }
            .syntaxhighlighter .keyword {
                color: #006699 !important;
            }
            .syntaxhighlighter .preprocessor {
                color: gray !important;
            }
            .syntaxhighlighter .variable {
                color: #aa7700 !important;
            }
            .syntaxhighlighter .value {
                color: #009900 !important;
            }
            .syntaxhighlighter .functions {
                color: #ff1493 !important;
            }
            .syntaxhighlighter .constants {
                color: #0066cc !important;
            }
            .syntaxhighlighter .script {
                font-weight: bold !important;
                color: #006699 !important;
                background-color: none !important;
            }
            .syntaxhighlighter .color1, .syntaxhighlighter .color1 a {
                color: gray !important;
            }
            .syntaxhighlighter .color2, .syntaxhighlighter .color2 a {
                color: #ff1493 !important;
            }
            .syntaxhighlighter .color3, .syntaxhighlighter .color3 a {
                color: red !important;
            }
            .syntaxhighlighter .keyword {
                font-weight: bold !important;
            }
    </style>
</head>
<body>
    <div id="container">
        <section id="main">
            <article class="post">
                <p>
                    Document number: P0077R1<br>
                    Supersedes: P0077R0, N4446<br>
                    Date: 2016-02-12<br>
                    Project: Programming Language C++, Library Working Group<br>
                    Reply-to: Agustín Bergé <a href="mailto:agustinberge@gmail.com">agustinberge@gmail.com</a>
                </p>

                <a name="`is_callable`-the-missing-_`invoke`_-related-trait" href="#`is_callable`-the-missing-_`invoke`_-related-trait">
                    <h1><code>is_callable</code>, the missing <em><code>INVOKE</code></em> related trait</h1>
                </a>

                <a name="0.-history" href="#0.-history">
                    <h2>0. History</h2>
                </a>

                <p>Changes from P0077R0:</p>

                <ul>
                    <li>Add type trait variables <code>is_callable_v</code>, <code>is_nothrow_callable_v</code>.</li>
                    <li>Adjust feature-testing macro for C++17.</li>
                    <li>Add appendix on addressing LWG2393 with <code>is_callable</code>.</li>
                </ul>

                <p>Changes from N4446:</p>

                <ul>
                    <li>Add discussion on alternative syntax.</li>
                    <li>Add discussion on additional nothrow trait, add <code>is_nothrow_callable</code>.</li>
                    <li>Add feature-testing macro recomendation.</li>
                    <li>Remove discussion on naming.</li>
                </ul>

                <a name="1.-introduction" href="#1.-introduction">
                    <h2>1. Introduction</h2>
                </a>

                <p>
                    This paper proposes to introduce a new trait to determine whether an
                    <em><code>INVOKE</code></em> expression is well formed.
                </p>

                <a name="2.-motivation" href="#2.-motivation">
                    <h2>2. Motivation</h2>
                </a>

                <p>
                    Starting with C++11, the library introduced the pseudo-macro <em><code>INVOKE</code></em> as a
way to uniformly handle function objects and member pointers as call
expressions. The trait <code>result_of</code> was made to follow <em><code>INVOKE</code></em> semantics
as well. This left users —who want to follow the precedent set forth by
the standard library— with the correct result type but no direct way of
obtaining such result, and <code>invoke</code> implementations proliferated.
                </p>

                <p>
                    This was recently rectified by the introduction of <code>invoke</code> to the working
draft [N4169]. However, there is still one piece of the puzzle missing, and is
the ability to query whether an <em><code>INVOKE</code></em> expression is well formed when
treated as an unevaluated operand. Such functionality is currently present in
the form of C++14 SFINAE-friendly <code>result_of</code>, albeit in a non user-friendly
way, and it should be made readily available in trait form for the same
reasons <code>invoke</code> was introduced into the library.
                </p>

                <p>The following is an artist depiction of such trait:</p>

                <div>
                    <div id="highlighter_654274" class="syntaxhighlighter nogutter  cpp">
                        <table border="0" cellpadding="0" cellspacing="0">
                            <tbody>
                                <tr>
                                    <td class="code">
                                        <div class="container">
                                            <div class="line number1 index0 alt2"><code class="cpp keyword bold">template</code> <code class="cpp plain">&lt;</code><code class="cpp keyword bold">class</code> <code class="cpp plain">T, </code><code class="cpp keyword bold">class</code> <code class="cpp plain">R = </code><code class="cpp keyword bold">void</code><code class="cpp plain">, </code><code class="cpp keyword bold">class</code> <code class="cpp plain">= </code><code class="cpp keyword bold">void</code><code class="cpp plain">&gt;</code></div>
                                            <div class="line number2 index1 alt1"><code class="cpp keyword bold">struct</code> <code class="cpp plain">is_callable</code></div>
                                            <div class="line number3 index2 alt2"><code class="cpp spaces">&nbsp;&nbsp;</code><code class="cpp plain">: false_type</code></div>
                                            <div class="line number4 index3 alt1"><code class="cpp plain">{};</code></div>
                                            <div class="line number5 index4 alt2">&nbsp;</div>
                                            <div class="line number6 index5 alt1"><code class="cpp keyword bold">template</code> <code class="cpp plain">&lt;</code><code class="cpp keyword bold">class</code> <code class="cpp plain">T&gt;</code></div>
                                            <div class="line number7 index6 alt2"><code class="cpp keyword bold">struct</code> <code class="cpp plain">is_callable&lt;T, </code><code class="cpp keyword bold">void</code><code class="cpp plain">, void_t&lt;result_of_t&lt;T&gt;&gt;&gt;</code></div>
                                            <div class="line number8 index7 alt1"><code class="cpp spaces">&nbsp;&nbsp;</code><code class="cpp plain">: true_type</code></div>
                                            <div class="line number9 index8 alt2"><code class="cpp plain">{};</code></div>
                                            <div class="line number10 index9 alt1">&nbsp;</div>
                                            <div class="line number11 index10 alt2"><code class="cpp keyword bold">template</code> <code class="cpp plain">&lt;</code><code class="cpp keyword bold">class</code> <code class="cpp plain">T, </code><code class="cpp keyword bold">class</code> <code class="cpp plain">R&gt;</code></div>
                                            <div class="line number12 index11 alt1"><code class="cpp keyword bold">struct</code> <code class="cpp plain">is_callable&lt;T, R, void_t&lt;result_of_t&lt;T&gt;&gt;&gt;</code></div>
                                            <div class="line number13 index12 alt2"><code class="cpp spaces">&nbsp;&nbsp;</code><code class="cpp plain">: is_convertible&lt;result_of_t&lt;T&gt;, R&gt;</code></div>
                                            <div class="line number14 index13 alt1"><code class="cpp plain">{};</code></div>
                                        </div>
                                    </td>
                                </tr>
                            </tbody>
                        </table>
                    </div>
                </div>

                <p>
                    This trait is implemented in the wild under different names, and the check for
a compatible result type is not always present. <a href="http://talesofcpp.fusionfenix.com/post-11/true-story-call-me-maybe" title="True Story: Call Me Maybe - Tales of C++">This post</a> [call-me-maybe]
shows how the implementation of such trait has been both improved and
simplified by every new standard.
                </p>

                <a name="3.-design-questions" href="#3.-design-questions">
                    <h2>3. Design questions</h2>
                </a>

                <a name="3.1-compatible-return-types" href="#3.1-compatible-return-types">
                    <h3>3.1 Compatible return types</h3>
                </a>

                <p>
                    <em><code>INVOKE</code></em> comes in two flavors, the primary <code>INVOKE(f, t1, t2, ..., tN)</code>
                    and <code>INVOKE(f, t1, t2, ..., tN, R)</code> defined as <code>INVOKE(f, t1, t2, ..., tN)</code>
                    implicitly converted to <code>R</code>. Both flavors can be supported with a defaulted
template argument:
                </p>

                <div>
                    <div id="highlighter_799951" class="syntaxhighlighter nogutter  cpp">
                        <table border="0" cellpadding="0" cellspacing="0">
                            <tbody>
                                <tr>
                                    <td class="code">
                                        <div class="container">
                                            <div class="line number1 index0 alt2"><code class="cpp keyword bold">template</code> <code class="cpp plain">&lt;</code><code class="cpp keyword bold">class</code><code class="cpp plain">, </code><code class="cpp keyword bold">class</code> <code class="cpp plain">R = </code><code class="cpp keyword bold">void</code><code class="cpp plain">&gt; </code><code class="cpp keyword bold">struct</code> <code class="cpp plain">is_callable; </code><code class="cpp comments">// not defined</code></div>
                                            <div class="line number2 index1 alt1"><code class="cpp keyword bold">template</code> <code class="cpp plain">&lt;</code><code class="cpp keyword bold">class</code> <code class="cpp plain">Fn, </code><code class="cpp keyword bold">class</code><code class="cpp plain">... ArgTypes, </code><code class="cpp keyword bold">class</code> <code class="cpp plain">R&gt;</code></div>
                                            <div class="line number3 index2 alt2"><code class="cpp spaces">&nbsp;&nbsp;</code><code class="cpp keyword bold">struct</code> <code class="cpp plain">is_callable&lt;Fn(ArgTypes...), R&gt;;</code></div>
                                        </div>
                                    </td>
                                </tr>
                            </tbody>
                        </table>
                    </div>
                </div>

                <p>
                    However, if only one of those flavors were to be supported there would be no
missing functionality, only more work for the user.
                </p>

                <a name="3.2-alternative-parameter-syntax" href="#3.2-alternative-parameter-syntax">
                    <h3>3.2 Alternative parameter syntax</h3>
                </a>

                <blockquote>
                    <p>Someone suggests alternative parameter syntax, <code>is_callable&lt;Fn, R(Args...)&gt;</code>.</p>

                    <p>Do we want AB to add consideration of the alternative syntax in the paper?</p>

                    <table>
                        <thead>
                            <tr>
                                <th align="center">SF</th>
                                <th align="center">F</th>
                                <th align="center">N</th>
                                <th align="center">A</th>
                                <th align="center">SA</th>
                            </tr>
                        </thead>
                        <tbody>
                            <tr>
                                <td align="center">0</td>
                                <td align="center">6</td>
                                <td align="center">5</td>
                                <td align="center">0</td>
                                <td align="center">0</td>
                            </tr>
                        </tbody>
                    </table>

                    <p>
                        But consistency between this and invocation_traits (in Fundamentals v1) is
  important.
                    </p>
                </blockquote>

                <p>
                    The syntax used by the invocation traits in the Library Fundamentals TS is
                    <code>Fn(Args...)</code>, which is consistent with the syntax used by <code>std::result_of</code>.
The optional trailing <code>R</code> for a checked compatible return type is consistent
with the alternative flavor of <em><code>INVOKE</code></em>.
                </p>

                <div>
                    <div id="highlighter_388478" class="syntaxhighlighter nogutter  cpp">
                        <table border="0" cellpadding="0" cellspacing="0">
                            <tbody>
                                <tr>
                                    <td class="code">
                                        <div class="container">
                                            <div class="line number1 index0 alt2"><code class="cpp keyword bold">template</code> <code class="cpp plain">&lt;</code><code class="cpp keyword bold">class</code> <code class="cpp plain">Fn, </code><code class="cpp keyword bold">class</code><code class="cpp plain">... ArgTypes&gt;</code></div>
                                            <div class="line number2 index1 alt1"><code class="cpp keyword bold">struct</code> <code class="cpp plain">invocation_type&lt;Fn(ArgTypes...)&gt;;</code></div>
                                            <div class="line number3 index2 alt2">&nbsp;</div>
                                            <div class="line number4 index3 alt1"><code class="cpp keyword bold">template</code> <code class="cpp plain">&lt;</code><code class="cpp keyword bold">class</code> <code class="cpp plain">Fn, </code><code class="cpp keyword bold">class</code><code class="cpp plain">... ArgTypes&gt;</code></div>
                                            <div class="line number5 index4 alt2"><code class="cpp keyword bold">struct</code> <code class="cpp plain">result_of&lt;Fn(ArgTypes...)&gt;;</code></div>
                                        </div>
                                    </td>
                                </tr>
                            </tbody>
                        </table>
                    </div>
                </div>

                <p>
                    For consistency with the rest of the standard library, the suggested syntax is
                    <code>Fn(ArgTypes...)</code> to represent an instance of a callable <code>Fn</code> invoked with
arguments of type <code>ArgTypes...</code>.
                </p>

                <a name="3.3-additional-nothrow-trait" href="#3.3-additional-nothrow-trait">
                    <h3>3.3 Additional nothrow trait</h3>
                </a>

                <blockquote>
                    <p>Add <code>is_noexcept_callable</code>?</p>

                    <table>
                        <thead>
                            <tr>
                                <th align="center">SF</th>
                                <th align="center">F</th>
                                <th align="center">N</th>
                                <th align="center">A</th>
                                <th align="center">SA</th>
                            </tr>
                        </thead>
                        <tbody>
                            <tr>
                                <td align="center">1</td>
                                <td align="center">4</td>
                                <td align="center">4</td>
                                <td align="center">2</td>
                                <td align="center">0</td>
                            </tr>
                        </tbody>
                    </table>
                </blockquote>

                <p>
                    Traits that check whether certain expressions involving special member
functions are well-formed also ship an additional <code>nothrow</code> trait, that
reports the result of applying the <code>noexcept</code> operator to the expression. It
is reasonable to provide a similar additional nothrow trait for <code>is_callable</code>,
                    <code>is_nothrow_callable</code>, that reports whether the given <em><code>INVOKE</code></em> expression is
known not to throw any exceptions.
                </p>

                <p>
                    It should be noted that the standard library does not specify an exception
specification for its callable types (like <code>reference_wrapper</code>), but a
conforming implementation may add a non-throwing noexcept-specification.
The result of <code>is_nothrow_callable</code> when a standard library callable type is
involved is thus implementation defined.
                </p>

                <a name="4.-feature-testing" href="#4.-feature-testing">
                    <h2>4. Feature-testing</h2>
                </a>

                <p>
                    For the purposes of SG10, we recommend a feature-testing macro named
                    <code>__cpp_lib_is_callable</code>.
                </p>

                <a name="5.-proposed-wording" href="#5.-proposed-wording">
                    <h2>5. Proposed Wording</h2>
                </a>

                <p>This wording is relative to [N4567].</p>

                <p>
                    Change 20.10.2 [meta.type.synop], header <code>&lt;type_traits&gt;</code> synopsis, as
indicated
                </p>

                <div>
                    <div id="highlighter_576168" class="syntaxhighlighter nogutter  cpp">
                        <table border="0" cellpadding="0" cellspacing="0">
                            <tbody>
                                <tr>
                                    <td class="code">
                                        <div class="container">
                                            <div class="line number1 index0 alt2"><code class="cpp keyword bold">namespace</code> <code class="cpp plain">std {</code></div>
                                            <div class="line number2 index1 alt1"><code class="cpp spaces">&nbsp;&nbsp;</code><code class="cpp plain">[...]</code></div>
                                            <div class="line number3 index2 alt2"><code class="cpp spaces">&nbsp;&nbsp;</code><code class="cpp comments">// 20.10.4.3, type properties:</code></div>
                                            <div class="line number4 index3 alt1"><code class="cpp spaces">&nbsp;&nbsp;</code><code class="cpp plain">[...]</code></div>
                                            <div class="line number5 index4 alt2"><code class="cpp spaces">&nbsp;&nbsp;</code><code class="cpp keyword bold">template</code> <code class="cpp plain">&lt;</code><code class="cpp keyword bold">class</code> <code class="cpp plain">T&gt; </code><code class="cpp keyword bold">struct</code> <code class="cpp plain">has_virtual_destructor;</code></div>
                                            <div class="line number6 index5 alt1">&nbsp;</div>
                                            <div class="line number8 index7 alt1"><code class="cpp spaces">&nbsp;&nbsp;</code><ins style="background-color: #A0FFA0;"><code class="cpp keyword bold">template</code> <code class="cpp plain">&lt;</code><code class="cpp keyword bold">class</code><code class="cpp plain">, </code><code class="cpp keyword bold">class</code> <code class="cpp plain">R = </code><code class="cpp keyword bold">void</code><code class="cpp plain">&gt; </code><code class="cpp keyword bold">struct</code> <code class="cpp plain">is_callable; </code><code class="cpp comments">// not defined</code></ins></div>
                                            <div class="line number9 index8 alt2"><code class="cpp spaces">&nbsp;&nbsp;</code><ins style="background-color: #A0FFA0;"><code class="cpp keyword bold">template</code> <code class="cpp plain">&lt;</code><code class="cpp keyword bold">class</code> <code class="cpp plain">Fn, </code><code class="cpp keyword bold">class</code><code class="cpp plain">... ArgTypes, </code><code class="cpp keyword bold">class</code> <code class="cpp plain">R&gt;</code></ins></div>
                                            <div class="line number10 index9 alt1"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><ins style="background-color: #A0FFA0;"><code class="cpp keyword bold">struct</code> <code class="cpp plain">is_callable&lt;Fn(ArgTypes...), R&gt;;</code></ins></div>
                                            <div class="line number11 index10 alt2">&nbsp;</div>
                                            <div class="line number12 index11 alt1"><code class="cpp spaces">&nbsp;&nbsp;</code><ins style="background-color: #A0FFA0;"><code class="cpp keyword bold">template</code> <code class="cpp plain">&lt;</code><code class="cpp keyword bold">class</code><code class="cpp plain">, </code><code class="cpp keyword bold">class</code> <code class="cpp plain">R = </code><code class="cpp keyword bold">void</code><code class="cpp plain">&gt; </code><code class="cpp keyword bold">struct</code> <code class="cpp plain">is_nothrow_callable; </code><code class="cpp comments">// not defined</code></ins></div>
                                            <div class="line number13 index12 alt2"><code class="cpp spaces">&nbsp;&nbsp;</code><ins style="background-color: #A0FFA0;"><code class="cpp keyword bold">template</code> <code class="cpp plain">&lt;</code><code class="cpp keyword bold">class</code> <code class="cpp plain">Fn, </code><code class="cpp keyword bold">class</code><code class="cpp plain">... ArgTypes, </code><code class="cpp keyword bold">class</code> <code class="cpp plain">R&gt;</code></ins></div>
                                            <div class="line number14 index13 alt1"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><ins style="background-color: #A0FFA0;"><code class="cpp keyword bold">struct</code> <code class="cpp plain">is_nothrow_callable&lt;Fn(ArgTypes...), R&gt;;</code></ins></div>
                                            <div class="line number16 index15 alt1">&nbsp;</div>
                                            <div class="line number17 index16 alt2"><code class="cpp spaces">&nbsp;&nbsp;</code><code class="cpp plain">[...]</code></div>
                                            <div class="line number18 index17 alt1"><code class="cpp spaces">&nbsp;&nbsp;</code><code class="cpp comments">// 20.10.4.3, type properties</code></div>
                                            <div class="line number19 index18 alt2"><code class="cpp spaces">&nbsp;&nbsp;</code><code class="cpp plain">[...]</code></div>
                                            <div class="line number20 index19 alt1"><code class="cpp spaces">&nbsp;&nbsp;</code><code class="cpp keyword bold">template</code> <code class="cpp plain">&lt;</code><code class="cpp keyword bold">class</code> <code class="cpp plain">T&gt; </code><code class="cpp keyword bold">constexpr</code> <code class="cpp color1 bold">bool</code> <code class="cpp plain">has_virtual_destructor_v</code></div>
                                            <div class="line number21 index20 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp plain">= has_virtual_destructor&lt;T&gt;::value;</code></div>
                                            <div class="line number22 index21 alt1">&nbsp;</div>
                                            <div class="line number24 index23 alt1"><code class="cpp spaces">&nbsp;&nbsp;</code><ins style="background-color: #A0FFA0;"><code class="cpp keyword bold">template</code> <code class="cpp plain">&lt;</code><code class="cpp keyword bold">class</code> <code class="cpp plain">T, </code><code class="cpp keyword bold">class</code> <code class="cpp plain">R = </code><code class="cpp keyword bold">void</code><code class="cpp plain">&gt; </code><code class="cpp keyword bold">constexpr</code> <code class="cpp color1 bold">bool</code> <code class="cpp plain">is_callable_v</code></ins></div>
                                            <div class="line number25 index24 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><ins style="background-color: #A0FFA0;"><code class="cpp plain">= is_callable&lt;T, R&gt;::value;</code></ins></div>
                                            <div class="line number26 index25 alt1">&nbsp;</div>
                                            <div class="line number27 index26 alt2"><code class="cpp spaces">&nbsp;&nbsp;</code><ins style="background-color: #A0FFA0;"><code class="cpp keyword bold">template</code> <code class="cpp plain">&lt;</code><code class="cpp keyword bold">class</code> <code class="cpp plain">T, </code><code class="cpp keyword bold">class</code> <code class="cpp plain">R = </code><code class="cpp keyword bold">void</code><code class="cpp plain">&gt; </code><code class="cpp keyword bold">constexpr</code> <code class="cpp color1 bold">bool</code> <code class="cpp plain">is_nothrow_callable_v</code></ins></div>
                                            <div class="line number28 index27 alt1"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><ins style="background-color: #A0FFA0;"><code class="cpp plain">= is_nothrow_callable&lt;T, R&gt;::value;</code></ins></div>
                                            <div class="line number30 index29 alt1">&nbsp;</div>
                                            <div class="line number31 index30 alt2"><code class="cpp spaces">&nbsp;&nbsp;</code><code class="cpp plain">[...]</code></div>
                                            <div class="line number32 index31 alt1"><code class="cpp plain">}</code></div>
                                        </div>
                                    </td>
                                </tr>
                            </tbody>
                        </table>
                    </div>
                </div>

                <p>
                    Change 20.10.4.3 [meta.unary.prop], Table 49 — Type property predicates, add
new rows with the following content:
                </p>

                <p><strong>Template</strong>:</p>

                <blockquote>
                    <div>
                        <div id="highlighter_707626" class="syntaxhighlighter nogutter  cpp">
                            <table border="0" cellpadding="0" cellspacing="0">
                                <tbody>
                                    <tr>
                                        <td class="code">
                                            <div class="container">
                                                <div class="line number1 index0 alt2"><code class="cpp keyword bold">template</code> <code class="cpp plain">&lt;</code><code class="cpp keyword bold">class</code> <code class="cpp plain">Fn, </code><code class="cpp keyword bold">class</code><code class="cpp plain">... ArgTypes, </code><code class="cpp keyword bold">class</code> <code class="cpp plain">R&gt;</code></div>
                                                <div class="line number2 index1 alt1"><code class="cpp keyword bold">struct</code> <code class="cpp plain">is_callable&lt;Fn(ArgTypes...), R&gt;;</code></div>
                                            </div>
                                        </td>
                                    </tr>
                                </tbody>
                            </table>
                        </div>
                    </div>
                </blockquote>

                <p><strong>Condition</strong>:</p>

                <blockquote>
                    <p>
                        The expression <code>INVOKE(declval&lt;Fn&gt;(), declval&lt;ArgTypes&gt;()..., R)</code> is well
  formed when treated as an unevaluated operand.
                    </p>
                </blockquote>

                <p><strong>Preconditions</strong>:</p>

                <blockquote>
                    <p>
                        <code>Fn</code> and all types in the parameter pack <code>ArgTypes</code> shall be complete types,
  (possibly cv-qualified) <code>void</code>, or arrays of unknown bound.
                    </p>
                </blockquote>

                <p><strong>Template</strong>:</p>

                <blockquote>
                    <div>
                        <div id="highlighter_857080" class="syntaxhighlighter nogutter  cpp">
                            <table border="0" cellpadding="0" cellspacing="0">
                                <tbody>
                                    <tr>
                                        <td class="code">
                                            <div class="container">
                                                <div class="line number1 index0 alt2"><code class="cpp keyword bold">template</code> <code class="cpp plain">&lt;</code><code class="cpp keyword bold">class</code> <code class="cpp plain">Fn, </code><code class="cpp keyword bold">class</code><code class="cpp plain">... ArgTypes, </code><code class="cpp keyword bold">class</code> <code class="cpp plain">R&gt;</code></div>
                                                <div class="line number2 index1 alt1"><code class="cpp keyword bold">struct</code> <code class="cpp plain">is_nothrow_callable&lt;Fn(ArgTypes...), R&gt;;</code></div>
                                            </div>
                                        </td>
                                    </tr>
                                </tbody>
                            </table>
                        </div>
                    </div>
                </blockquote>

                <p><strong>Condition</strong>:</p>

                <blockquote>
                    <p>
                        <code>is_callable&lt;Fn(ArgTypes...), R&gt;::value</code> is <code>true</code> and the expression
 
                        <code>INVOKE(declval&lt;Fn&gt;(), declval&lt;ArgTypes&gt;()..., R)</code> is known not to throw any
  exception.
                    </p>
                </blockquote>

                <p><strong>Preconditions</strong>:</p>

                <blockquote>
                    <p>
                        <code>Fn</code> and all types in the parameter pack <code>ArgTypes</code> shall be complete types,
  (possibly cv-qualified) <code>void</code>, or arrays of unknown bound.
                    </p>
                </blockquote>

                <a name="6.-references" href="#6.-references">
                    <h2>6. References</h2>
                </a>

                <ul>
                    <li>
                        <p>
                            [N4567] ISO/IEC JTC1 SC22 WG21, Programming Languages - C++, working draft, November 2015
                            <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4567.pdf">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4567.pdf</a>
                        </p>
                    </li>
                    <li>
                        <p>
                            [call-me-maybe] True Story: Call Me Maybe - Tales of C++
                            <a href="http://talesofcpp.fusionfenix.com/post-11/true-story-call-me-maybe">http://talesofcpp.fusionfenix.com/post-11/true-story-call-me-maybe</a>
                        </p>
                    </li>
                    <li>
                        <p>
                            [N4169] A proposal to add invoke function template (Revision 1) - Tomasz Kaminski
                            <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4169.html">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4169.html</a>
                        </p>
                    </li>
                </ul>

                <a name="a.-an-alternative-resolution-for-lwg2393-informative" href="#a.-an-alternative-resolution-for-lwg2393-informative">
                    <h2>A. An alternative resolution for LWG2393 (informative)</h2>
                </a>

                <p>
                    In <a href="http://cplusplus.github.io/LWG/lwg-defects.html#2132" title="std::function ambiguity - C++ Standard Library Defect Report List">LWG2132</a>
                    <code>is_callable</code> is suggested as an alternative to <em>Callable</em> in order to make
the wording clear:
                </p>

                <blockquote>
                    <p>
                        STL strongly wants to see an <code>is_callable</code> type trait to clarify the
  proposed wording.
                    </p>
                </blockquote>

                <p>
                    In <a href="http://cplusplus.github.io/LWG/lwg-active.html#2393" title="std::function's Callable definition is broken - C++ Standard Library Defect
Report List">LWG2393</a> the definition of <em>Callable</em> is fixed and renamed to
                    <em>Lvalue-Callable</em>. Here is how the proposed resolution would look like if it
were to use <code>is_callable</code> instead, as suggested:
                </p>

                <p>Change 20.9.12.2 [func.wrap.func] p2, as indicated:</p>

                <blockquote>
                    <p>
                        <del style="background-color: #FFA0A0;">A callable object <code>f</code> of type <code>F</code> is <em>Callable</em> for argument types
 
                            <code>ArgTypes</code> and return type <code>R</code> if the expression <code>INVOKE(f,
  declval&lt;ArgTypes&gt;()..., R)</code>, considered as an unevaluated operand (Clause
  5), is well formed (20.9.2).</del>
                    </p>
                </blockquote>

                <p>Change 20.9.12.2.1 [func.wrap.func.con] p8+p21, as indicated:</p>

                <blockquote>
                    <div>
                        <div id="highlighter_573047" class="syntaxhighlighter nogutter  cpp">
                            <table border="0" cellpadding="0" cellspacing="0">
                                <tbody>
                                    <tr>
                                        <td class="code">
                                            <div class="container">
                                                <div class="line number1 index0 alt2"><code class="cpp keyword bold">template</code> <code class="cpp plain">&lt;</code><code class="cpp keyword bold">class</code> <code class="cpp plain">F&gt; function(F f);</code></div>
                                                <div class="line number2 index1 alt1"><code class="cpp keyword bold">template</code> <code class="cpp plain">&lt;</code><code class="cpp keyword bold">class</code> <code class="cpp plain">F, </code><code class="cpp keyword bold">class</code> <code class="cpp plain">A&gt; function(allocator_arg_t, </code><code class="cpp keyword bold">const</code> <code class="cpp plain">A&amp; a, F f);</code></div>
                                            </div>
                                        </td>
                                    </tr>
                                </tbody>
                            </table>
                        </div>
                    </div>

                    <p>
                        <em>Remarks</em>: These constructors shall not participate in overload resolution
  unless <del style="background-color: #FFA0A0;"><code>f</code> is <em>Callable</em> (20.9.12.2) for argument types <code>ArgTypes...</code>
      and return type <code>R</code></del><ins style="background-color: #A0FFA0;"><code>is_callable&lt;F&amp;(ArgTypes...), R&gt;::value</code> is
 
                                <code>true</code></ins>.
                    </p>

                    <div>
                        <div id="highlighter_389288" class="syntaxhighlighter nogutter  cpp">
                            <table border="0" cellpadding="0" cellspacing="0">
                                <tbody>
                                    <tr>
                                        <td class="code">
                                            <div class="container">
                                                <div class="line number1 index0 alt2"><code class="cpp keyword bold">template</code><code class="cpp plain">&lt;</code><code class="cpp keyword bold">class</code> <code class="cpp plain">F&gt; function&amp; </code><code class="cpp keyword bold">operator</code><code class="cpp plain">=(F&amp;&amp; f);</code></div>
                                            </div>
                                        </td>
                                    </tr>
                                </tbody>
                            </table>
                        </div>
                    </div>

                    <p>
                        <em>Remarks</em>: This assignment operator shall not participate in overload
  resolution unless <del style="background-color: #FFA0A0;"><code>declval&lt;decay_t&lt;F&gt;&amp;&gt;()</code> is <em>Callable</em> (20.9.12.2) for
  argument types <code>ArgTypes...</code> and return type <code>R</code></del>
                        <ins style="background-color: #A0FFA0;"><code>is_callable&lt;decay_t&lt;F&gt;&amp;(ArgTypes...), R&gt;::value</code> is <code>true</code></ins>.
                    </p>
                </blockquote>

                <p>Change 20.9.12.2.5 [func.wrap.func.targ] p2, as indicated:</p>

                <blockquote>
                    <div>
                        <div id="highlighter_663068" class="syntaxhighlighter nogutter  cpp">
                            <table border="0" cellpadding="0" cellspacing="0">
                                <tbody>
                                    <tr>
                                        <td class="code">
                                            <div class="container">
                                                <div class="line number1 index0 alt2"><code class="cpp keyword bold">template</code> <code class="cpp plain">&lt;</code><code class="cpp keyword bold">class</code> <code class="cpp plain">T&gt; T* target() </code><code class="cpp keyword bold">noexcept</code><code class="cpp plain">;</code></div>
                                                <div class="line number2 index1 alt1"><code class="cpp keyword bold">template</code> <code class="cpp plain">&lt;</code><code class="cpp keyword bold">class</code> <code class="cpp plain">T&gt; </code><code class="cpp keyword bold">const</code> <code class="cpp plain">T* target() </code><code class="cpp keyword bold">const</code> <code class="cpp keyword bold">noexcept</code><code class="cpp plain">;</code></div>
                                            </div>
                                        </td>
                                    </tr>
                                </tbody>
                            </table>
                        </div>
                    </div>

                    <p>
                        <em>Requires</em>: <del style="background-color: #FFA0A0;"><code>T</code> shall be a type that is <em>Callable</em> (20.9.12.2) for
  parameter types <code>ArgTypes</code> and return type <code>R</code></del>
                        <ins style="background-color: #A0FFA0;"><code>is_callable&lt;remove_cv_t&lt;T&gt;&amp;(ArgTypes...), R&gt;::value</code> shall be <code>true</code>
                        </ins>.
                    </p>

                    <p>
                        <em>Returns</em>: If <code>target_type() == typeid(T)</code> a pointer to the stored function
  target; otherwise a null pointer.
                    </p>
                </blockquote>

                <p>
                    Note that <code>remove_cv_t</code> is needed here in order to match <code>typeid(T)</code>, which
strips references and cv-qualifiers but does not <code>decay</code>. Otherwise, it is
possible to run into situations in which the <code>target_type() == typeid(T)</code>
                    check returns <code>true</code> but a subsequent <code>target&lt;T&gt;()</code> call yields undefined
behavior:
                </p>

                <div>
                    <div id="highlighter_306136" class="syntaxhighlighter nogutter  cpp">
                        <table border="0" cellpadding="0" cellspacing="0">
                            <tbody>
                                <tr>
                                    <td class="code">
                                        <div class="container">
                                            <div class="line number1 index0 alt2"><code class="cpp keyword bold">struct</code> <code class="cpp plain">foo {</code></div>
                                            <div class="line number2 index1 alt1"><code class="cpp spaces">&nbsp;&nbsp;</code><code class="cpp color1 bold">int</code> <code class="cpp keyword bold">operator</code><code class="cpp plain">()() { </code><code class="cpp keyword bold">return</code> <code class="cpp plain">0; }</code></div>
                                            <div class="line number3 index2 alt2"><code class="cpp spaces">&nbsp;&nbsp;</code><code class="cpp keyword bold">void</code> <code class="cpp keyword bold">operator</code><code class="cpp plain">()() </code><code class="cpp keyword bold">const</code> <code class="cpp plain">{}</code></div>
                                            <div class="line number4 index3 alt1"><code class="cpp plain">};</code></div>
                                            <div class="line number5 index4 alt2">&nbsp;</div>
                                            <div class="line number6 index5 alt1"><code class="cpp color1 bold">int</code> <code class="cpp plain">main() {</code></div>
                                            <div class="line number7 index6 alt2"><code class="cpp spaces">&nbsp;&nbsp;</code><code class="cpp color1 bold">std::function</code><code class="cpp plain">&lt;</code><code class="cpp color1 bold">int</code><code class="cpp plain">()&gt; fun = foo{};</code></div>
                                            <div class="line number8 index7 alt1"><code class="cpp spaces">&nbsp;&nbsp;</code><code class="cpp functions bold">assert</code><code class="cpp plain">(fun.target_type() == </code><code class="cpp keyword bold">typeid</code><code class="cpp plain">(foo </code><code class="cpp keyword bold">const</code><code class="cpp plain">)); </code><code class="cpp comments">// holds</code></div>
                                            <div class="line number9 index8 alt2"><code class="cpp spaces">&nbsp;&nbsp;</code><code class="cpp plain">fun.target&lt;foo </code><code class="cpp keyword bold">const</code><code class="cpp plain">&gt;(); </code><code class="cpp comments">// undefined behavior</code></div>
                                            <div class="line number10 index9 alt1"><code class="cpp plain">}</code></div>
                                        </div>
                                    </td>
                                </tr>
                            </tbody>
                        </table>
                    </div>
                </div>

                <p>
                    There is no need for <code>remove_reference_t</code> given that the return type <code>T*</code>
                    already makes these functions ill-formed for reference types.
                </p>
            </article>
        </section>
    </div>
</body>
</html>
