﻿<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <!-- TITLE -->
    <title>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: N4446<br>
                    Date: 2015-04-09<br>
                    Project: Programming Language C++, Library Evolution Working Group<br>
                    Reply-to: Agustín Bergé <a href="mailto:agustinberge@gmail.com">agustinberge@gmail.com</a>
                </p>
                <a name="the-missing-_`invoke`_-related-trait" href="#the-missing-_`invoke`_-related-trait"><h1>The missing <em><code>INVOKE</code></em> related trait</h1></a>
                <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 precedence 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_936682" 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-naming" href="#3.1-naming"><h3>3.1 Naming</h3></a>
                <p>
                    The property this trait determines is usually referred to as whether something
                    is <em>callable</em> with given arguments [citation needed], a name dating from
                    before <em><code>INVOKE</code></em> was introduced. But perhaps <em>callable</em> is not the most
                    appropriate name, as the standard already defines a number of things by that
                    name:
                </p>
                <blockquote>
                    <p>
                        <strong>20.9.1 [func.def]/3</strong>
                        A <em>callable</em> type is a function object type or a pointer to member.
                    </p>

                    <p>
                        <strong>20.9.1 [func.def]/4</strong>
                        A <em>callable object</em> is an object of a callable type.
                    </p>
                </blockquote>
                <p>
                    These definitions of callable do not represent what the trait would do.
                    Knowing whether some object is a function object or pointer to member is
                    meaningless, as it does not tell whether operating on such an object would be
                    well formed.
                </p>
                <p>
                    The following definition of —proper cased— <em>Callable</em>, introduced
                    and used only by <code>std::function</code>, matches exactly what the trait would do:
                </p>
                <blockquote>
                    <p>
                        <strong>20.9.12.2 [func.wrap.func]/2</strong>
                        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, is well
                        formed.
                    </p>
                </blockquote>
                <p>
                    The rest of the standard library simply requires <em><code>INVOKE</code></em> expressions being
                    well formed.
                </p>
                <p>
                    The ranges proposal [N4128] uses the term <em>invokable</em> instead, for things
                    that work with <em><code>INVOKE</code></em>, and defines an <code>Invokable</code> concept.
                </p>
                <a name="3.2-compatible-return-types" href="#3.2-compatible-return-types"><h3>3.2 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_625532" 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>
                    <em>[Note:</em> This assumes that the resolution for LWG2420 makes
                    <code>INVOKE(f, t1, t2, ..., tN, void)</code> discard the return type. <em>-end note]</em>
                </p>
                <p>
                    However, if only one of those flavors would be supported there would be no
                    missing functionality, only more work for the user.
                </p>
                <a name="4.-proposed-wording" href="#4.-proposed-wording"><h2>4. Proposed Wording</h2></a>
                <p>This wording is relative to [N4296].</p>
                <p>
                    Change 20.10.2 [meta.type.synop], header <code>&lt;type_traits&gt;</code> synopsis, as
                    indicated:
                </p>
                <blockquote>
                    <div>
                        <div id="highlighter_625976" 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">is_nothrow_destructible;</code></div>
                                                <div class="line number6 index5 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">struct</code> <code class="cpp plain">has_virtual_destructor;</code></div>
                                                <div class="line number7 index6 alt2">&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><code class="cpp plain">[...]</code></div>
                                                <div class="line number13 index12 alt2"><code class="cpp plain">}</code></div>
                                            </div>
                                        </td>
                                    </tr>
                                </tbody>
                            </table>
                        </div>
                    </div>
                </blockquote>
                <p>
                    Change 20.10.4.3 [meta.unary.prop], Table 49 — Type property predicates, add
                    a new row with the following contents:
                </p>
                <p><strong>Template</strong>:</p>
                <blockquote>
                    <div>
                        <div id="highlighter_119097" 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>
                <a name="5.-references" href="#5.-references"><h2>5. References</h2></a>
                <ul>
                    <li>
                        <p>
                            [N4296] ISO/IEC JTC1 SC22 WG21, Programming Languages - C++, working draft, November 2014
                            <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4296.pdf">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4296.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>
                    <li>
                        <p>
                            [N4128] Ranges for the Standard Library, Revision 1 - Eric Niebler, Sean Parent, Andrew Sutton
                            <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4128.html">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4128.html</a>
                        </p>
                    </li>
                </ul>
            </article>
        </section>
    </div>
</body>
</html>
