<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content= "text/html; charset=UTF-8"/>
<title>std::result_of and SFINAE</title>

<style type="text/css" media="screen,print">
    blockquote {
      font-family: serif;
      font-style: normal;
      text-align: justify;
      width: 675px;
    }
    ins {
      text-decoration: none;
      font-weight: bold;
      background-color:#A0FFA0;  /* green */
    }

    del {
      text-decoration: line-through;
      background-color: #FFA0A0; /* red */
    }
    dt:after {
      font-style: normal;
      content:":";
    }

    sub, .op:after,
    var, .v, dt
    /* Style for grammar terms */
    {
      font-style: italic;
      font-family: serif;
    }
    sub, .op:after {
      vertical-align: sub;
      font-size: .70em;
    }

    dl {
      background-color: inherit;
    }

    dt  {
      padding-top: .5em;
      margin-left: 40px;
    }
    dd  {
      word-spacing: .5em;
      margin-left: 160px;
      text-indent: -80px;
    }
    .m, tt  {
      font-family: monospace;
      font-style: normal;
    }
    .op:after { content: 'opt'; }
    .cm /* For comments in C++ example code */ {
      font-style: italic;
      font-family: serif;
      display: inline;
    }
    .cm:before { content:'// ' }

    /*  The following was part of a failed attempt to set the initial
    numeric value of a marker in a display-item while maintaining
    conformance to XHTML strict.  Since I don't know how to make that work
    (yet) I use 'start="N"' (on the 'ol' element) instead.    */
    /*
      blockquote > ol > li:before {
        counter-increment:asdf;
        content: counter(asdf);
        display: marker;
      }
      */

    blockquote ul {
      padding-top: 1em;
      background-color: inherit;
    }
    blockquote li {
      padding-bottom: 0.5em;
    }

    .ex:before {
      display: block;
      font-family: serif;
      font-style: italic;
      content: '  [Example:\a\a';
    }

    .ex {
      background-color: inherit;
      display: inline;
      font-size: 0.9em;
      }


    .ex:after {
      display: block;
      font-family: serif;
      font-style: italic;
      content: '\a\a? ?  end example]';
    }

    .note:before {
      font-family: serif;
      font-style: italic;
      content: '  [ Note:? ? ';
    }
    .note {
      display: inline;
    }
    .note:after {
      font-family: serif;
      font-style: italic;
      content: '  end note ]? ? '
    }

    .footnote:before {
      font-family: serif;
      font-style: italic;
      content: '  [ Footnote:? ? ';
    }
    .footnote {
      display: inline;
    }
    .footnote:after {
      font-family: serif;
      font-style: italic;
      content: ' -- end footnote ]? ? '
    }

    td { vertical-align: top; }
</style>
</head>
  
<body>
<h1>std::result_of and SFINAE</h1>
<p>ISO/IEC JTC1 SC22 WG21 N3436=12-0126 - 2012-09-21</p>

<p>Eric Niebler (eric.niebler@gmail.com)<br/>
Daniel Walker (daniel.j.walker@gmail.com)<br/>
Joel de Guzman (djowel@gmail.com)</p>

<p>This paper deals with the use of <code>result_of</code> in contexts where SFINAE is a consideration; i.e., in function signatures. <code>result_of</code> is intended to be a simple way to compute the result type of some callable when provided with arguments of specified types. It is a shorthand for a longer type computation using <code>decltype</code> and <code>declval</code>. However, there are cases where the use of <code>result_of</code> leads to a hard error whereas the equivalent use of <code>decltype</code> and <code>declval</code> would not. This happens in function signatures, when the direct use of <code>decltype</code> of an ill-formed call expression causes the function to be dropped due to SFINAE.</p>

<p>This paper addresses the issue by making <code>result_of</code> SFINAE-friendly. It does this by conditioning the presence of the nested <code>type</code> typedef on whether the call expression is ill-formed or not.</p>

<p>This paper will do the following:</p>

<ul>
<li>Demonstrate the issue.</li>
<li>Present complaints from users demonstrating that the current behavior is unsatisfactory.</li>
<li>Suggest core wording changes that will address the problem.</li>
<li>Weigh the pros and cons of accepting this resolution vs. others.</li>
</ul>

<!-- TABLE OF CONTENTS -->
<p>
<a href="#Problem">Problem</a><br/>
&#160;&#160;&#160;&#160;<a href="#TrivialExample">Trivial Example</a><br/>
&#160;&#160;&#160;&#160;<a href="#FieldExperience">Reports From The Field</a><br/>
<a href="#Solution">Solution</a><br/>
&#160;&#160;&#160;&#160;<a href="#ProposedResolution">Proposed Resolution</a><br/>
&#160;&#160;&#160;&#160;<a href="#OptionsConsideredAndDismissed">Options Considered and Dismissed</a><br/>
&#160;&#160;&#160;&#160;<a href="#ImplementationExperience">Implementation Experience</a><br/>
<a href="#Acknowledgements">Acknowledgements</a><br/>
<a href="#AppendixA">Appendix A: Example of an Error in a Non-Immediate Context</a>
</p>

<h2><a name="Problem" id="Problem">Problem</a></h2>

<p>The direct use of <code>decltype</code> in a function signature would cause SFINAE to kick in when the expression in the <code>decltype</code> is invalid. In contrast, the use of <code>result_of</code> in a function signature, as it is currently specified, causes a hard error because the call expression appears in a non-SFINAE context: within the definition of the nested <code>type</code> typedef.</p>

<h3><a name="TrivialExample" id="TrivialExample">Trivial Example</a></h3>
<p>Below is a program that compiles when the return type is declared using <code>decltype</code>, but that fails to compile when using <code>result_of</code>.</p>

<blockquote>
<pre>
<code>
//#define BUGBUG
#include &lt;type_traits&gt;
#include &lt;utility&gt;
#include &lt;string&gt;

struct eat { template&lt;typename T&gt; eat(T const &amp;) {} };
struct not_incrementable {};

struct inc {
    template&lt;typename T&gt;
    auto operator()(T t) const -&gt; decltype(t++)
        { return t++; }
};

template&lt;typename A&gt;
#ifdef BUGBUG
  typename std::result_of&lt;inc(A)&gt;::type            // HARD ERROR HERE
#else
  decltype(std::declval&lt;inc&gt;()(std::declval&lt;A&gt;())) // SFINAE HERE
#endif
try_inc(A a) {
    return inc()(a);
}

not_incrementable try_inc(eat) {
    return not_incrementable();
}

int main() {
    int x = try_inc(1); // OK
    not_incrementable y = try_inc(std::string("foo")); // OK, not_incrementable
}
</code>
</pre>
</blockquote>

<h3><a name="FieldExperience" id="FieldExperience">Reports From The Field</a></h3>
<p>You might wonder if this is really a problem that needs to be fixed, or whether instead it is simply a case of people misusing <code>result_of</code>. Even if <code>result_of</code> were never intended to be used this way, there is evidence that users find the current behavior unsatisfactory:</p>

<dl>

<dt><b><a href="http://www.boost.org">Boost</a></b></dt>
<dd>When <code>boost::result_of</code> was switched to use <code>decltype</code>, some of Boost's tests started failing. After investigation, we discovered that the TR1-style <code>result_of</code> had been implemented such that it was SFINAE-friendly, and that folks had discovered this and come to rely on it. The amount of affected code within Boost was small, but Boost became concerned about its downstream users and are now in the process of making their <code>decltype</code>-based <code>result_of</code> SFINAE-friendly to prevent downstream breakage. (Aside: the problems in Boost have already been found by users and reported both on <a href="http://stackoverflow.com/questions/10632848/boost-fusion-invoke-and-sfinae">StackOverflow</a> and in <a href="https://svn.boost.org/trac/boost/ticket/6915">Boost's bug tracker</a>.)</dd>

<dt><b><a href="http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50711">GCC bug report</a></b></dt>
<dd>The linked bug report, entitled "substitution failure reports error with result_of", describes this problem. Says Paolo Carlini:<blockquote><p>"Unfortunately, I don't think you can use std::result_of for sfinae purposes, if I understand correctly it's a well know annoyance which you have to overcome by open coding with std::declval."</p></blockquote></dd>

<dt><b><a href="http://lwg.github.com/issues/lwg-defects.html#1225">LWG DR1225</a></b></dt>
<dd>The submitter of DR1225 wants <code>std::result_of</code> to be SFINAE-friendly (among other things) and offers wording. He is under the impression that this change would require compiler support (perhaps in order to correctly handle errors in the non-immediate instantiation context; see <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1227">CWG DR1227</a>). This part of the DR was rejected, the rationale given being: "The wish to change <code>result_of</code> into a compiler-support trait was beyond the actual intention of the submitter Sebastian." Note that a SFINAE-friendly <code>result_of</code> can be implemented in standard C++11, at least insofar as it be allowed to fail when the first error appears in a non-immediate context (see <a href="#AppendixA">Appendix A</a>).</dd>

<dt><b><a href="http://thread.gmane.org/gmane.comp.lib.boost.user/9967/focus=10030">Complaints from Boost's Users</a></b></dt>
<dd><blockquote><p>  From: Ian McCulloch<br/>
  Subject: Re: result_of tutorial<br/>
  Date: 2005-03-17 08:22:29 GMT<br/>
<br/>
  Thanks Peter, I think I understand how it works now.  Unfortunately, the
  lack of SFINAE is a real showstopper for me.  I want to write functions
  like<br/>
<br/>
  template &lt;typename T&gt;<br/>
  typename result_of&lt;negate(T)&gt;::type<br/>
  operator-(T const&amp; x)<br/>
  {<br/>
  &#160;&#160;&#160;return negate()(x);<br/>
  }<br/>
<br/>
  but the lack of SFINAE here makes boost::result_of essentially useless for
  this.  But I imagine it won't be difficult to make a new version based on
  boost that would work."</p></blockquote></dd>

<dt><b><a href="http://d.hatena.ne.jp/gintenlabo/20110420/1303288950">A Blog Post</a></b></dt>
<dd>Although written in Japanese, the author shows an <code>invoke</code> function defined with <code>result_of</code> that fails to compile because it (<code>result_of</code>) is not SFINAE-friendly. It also calls out <code>std::common_type</code> as another trait that would benefit from being SFINAE-friendly.</dd>
</dl>

<h2><a name="Solution" id="Solution">Solution</a></h2>

<h3><a name="Solution_Notes" id="Solution_Notes">Notes About the Proposed Wording Change</a></h3>

<p>
The intention of the proposed change is to condition the presence of the nested <code>type</code> typedef of <code>result_of</code> on whether the call expression used in the <var>decltype-specifier</var> is well-formed. The changes occur in Table 57 (section 20.9.7.6, [meta.trans.other]). An attempt is made at the standardese to permit <code>result_of</code> to issue a hard error if and only if the first error is encountered in a non-immediate context. This bit of language borrows heavily from the specification of <code>is_assignable</code> in Table 49 (section 20.9.4.3, [meta.trans.unary]). (See <a href="#AppendixA">Appendix A</a> for an example of an error in a non-immediate context.)
</p>

<h3><a name="ProposedResolution" id="ProposedResolution">Proposed Resolution</a></h3>

<div id="result_of_and_sfinae">
    <ul>

    <li>
        <p>Change the last line of Table 53 as indicated:</p>
        <blockquote>
            <table border="1">
            <tr>

            <td><code>template &lt;class Fn,<br/>
class... ArgTypes&gt; struct<br/>
result_of&lt;Fn(ArgTypes...)&gt;;</code></td>

            <td><code>Fn</code> shall be a callable<br/>
type (20.8.1), reference to<br/>
function, or reference to<br/>
callable type.<del> The<br/>
expression<br/>
<code>decltype(INVOKE(declval&lt;Fn&gt;(),<br/>
declval&lt;ArgTypes&gt;()...))</code> shall<br/>
be well formed.</del></td>

            <td><ins>If the expression<br/>
<code>INVOKE(declval&lt;Fn&gt;(),<br/>
declval&lt;ArgTypes&gt;()...)</code><br/>
is well formed when treated as an unevaluated operand (Clause 5), t</ins><del>T</del>he member typedef <code>type</code> shall name the type<br/>
<code>decltype(INVOKE(declval&lt;Fn&gt;(),<br/>
declval&lt;ArgTypes&gt;()...))</code><ins>; otherwise, no such member<br/>
typedef shall exist. Access checking<br/>
is performed as if in a context<br/>
unrelated to <code>Fn</code> and <code>ArgTypes</code>.<br/>
Only the validity of the immediate<br/>
context of the expression is<br/>
considered. [ Note: The<br/>
compilation of the expression can<br/>
result in side effects such as the<br/>
instantiation of class template<br/>
specializations and function<br/>
template specializations, the<br/>
generation of implicitly-defined<br/>
functions, and so on. Such side<br/>
effects are not in the "immediate<br/>
context" and can result in the<br/>
program being ill-formed.<br/>
-end note ]</ins></td>
            </tr>
            </table>
        </blockquote>
    </li>

    </ul>

</div>

<h3><a name="OptionsConsideredAndDismissed" id="OptionsConsideredAndDismissed">Options Considered and Dismissed</a></h3>

<p>Eric Niebler started a discussion on the -lib reflector about <code>result_of</code> and SFINAE in c++std-lib-32993. Below are some of the considerations brought up in the ensuing thread, and the authors' thoughts.</p>

<h4>Should <code>result_of</code> simply be deprecated?</h4>

<p>In c++std-lib-32999, Nikolay Ivchenkov floats the idea that <code>result_of</code> be deprecated, thereby solving the SFINAE problem by encouraging users to use <code>decltype</code> and <code>declval</code> directly. Others (namely Howard Hinnant and Pete Becker) echoed Nikolay's sentiment that <code>result_of</code>'s unconventional use of function types is confusing to some users. In c++std-lib-33010, Anthony Williams points out that <code>result_of&lt;X(Y)&gt;::type</code> is simpler than the equivalent type calculation involving <code>decltype</code> and <code>declval</code>. The authors of this paper agree and do not recommend deprecating <code>result_of</code>.</p>

<h4>Should <code>result_of</code> be implemented in terms of more general and idiomatic traits?</h4>

<p>In c++std-lib-33011, Howard Hinnant described an interface that he has come to prefer: <code>std::invoke_of</code> and <code>std::invokable</code>. Rather than taking one template argument of function type, <code>invoke_of</code> would take <var>N</var> parameters, the first of which is the callable type and the rest are the types of the arguments. <code>invokable</code> is a Boolean trait that takes the same parameters and computes whether the specified call expression is well-formed or not. <code>result_of</code> is trivially implemented in terms of such traits.</p>

<p>The authors of this paper are not opposed to this change. It is, however, a larger change than necessary. As such, the authors are not proposing it here. Note that adopting the resolution suggested in this paper would not block any future proposal that recommends such a change.</p>

<h4>Shouldn't we also address the other traits that could be made SFINAE-friendly?</h4>

<p>As noted by some users and by Marc Glisse in c++std-lib-32994, <code>result_of</code> is far from the only trait that could benefit from the SFINAE treatment. <code>iterator_traits</code> and <code>common_type</code> are obvious candidates. The authors of this paper have chosen to narrowly focus on <code>result_of</code> for lack of time.</p>

<h3><a name="ImplementationExperience" id="ImplementationExperience">Implementation Experience</a></h3>

<p>Has this been implemented yet? Yes. In c++std-lib-33002, Howard Hinnant claims that his <a href="http://libcxx.llvm.org">libc++</a> library has already shipped a SFINAE-friendly <code>result_of</code>. In c++std-lib-33013, he links to his implementation. It can be found at <a href="http://llvm.org/svn/llvm-project/libcxx/trunk/include/type_traits">http://llvm.org/svn/llvm-project/libcxx/trunk/include/type_traits</a>.</p>

<p>Also, Boost recently switched to a SFINAE-friendly <code>result_of</code>, although it hasn't shipped it yet at the time of writing (2012-09-20).</p>

<h2><a name="Acknowledgements" id="Acknowledgements">Acknowledgements</a></h2>

<p>
Many thanks to those on the committee reflector who provided feedback about this issue; namely, Marc Glisse, Nikolay Ivchenkov, David Abrahams, Anthony Williams, Pete Becker, Peter Dimov, Doug Gregor and Daniel Kr&#252;gler. Thanks are also due to the Boost users and developers who pushed for this change and made suggestions, especially Michel Morin and Jeffrey Lee Hellrung, Jr.
</p>

<hr/>

<h3><a name="AppendixA" id="AppendixA">Appendix A: Example of an Error in a Non-Immediate Context</a></h3>

<p>The current proposal allows that while testing an expression for well-formed-ness, a hard error can occur. No attempt is made to make <code>result_of</code> usable with such "indirectly" ill-formed expressions. Below is an example of a callable expression that will trigger a hard error, regardless of whether <code>result_of</code> is "SFINAE-friendly" or not.</p>

<blockquote>
<code>
<pre>
template<class X>
struct Fail
{
  static_assert(sizeof(X)==0,"duh");
  typedef int type;
};

struct Fun
{
  template<class T>
  typename Fail<T>::type operator()(T)
      { return 0; }
};

template<typename T>
typename std::result_of<Fun(T)>::type foo(T)
   { return 0; }

template<typename T>
int foo(...)
   { return 0; }

int main()
{
   foo(0);
}
</pre>
</code>
</blockquote>

</body>
</html>
