<?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 name="generator" content= "HTML Tidy for Windows (vers 25 March 2009), see www.w3.org"/>
<meta http-equiv="Content-Type" content= "text/html; charset=UTF-8"/>
<title>Decltype and Call Expressions</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>US22/DE9 Revisited: Decltype and Call Expressions</h1>
<p>ISO/IEC JTC1 SC22 WG21 N3233=11‑0003 - 2011‑02‑25</p>
<p>Eric Niebler (eric.niebler@gmail.com)<br/>
Doug Gregor (doug.gregor@gmail.com)<br/>
James Widman (widman@gimpel.com)</p>
<p>This paper deals with US22/DE9, which mistakenly attributed a
type-completeness requirement to any expression argument of
<code>decltype</code>, but which was nevertheless trying to call
attention to a real problem: that when the expression of a
<var>decltype-specifier</var> is a function call expression, the
longstanding requirement for a call-expression's type to be
complete (from 5.2.2 [expr.call]) is both unnecessary and harmful.
In that limited context, this old requirement causes unexpected and
catastrophic problems. The committee decided in Rapperswil that
this issue was NAD. The authors of this paper believe the issues
caused by that requirement are real and very serious, possibly
leading to poor adoption of <code>decltype</code> and
<code>result_of</code>.<br/>
<br/>
This paper will do the following:<br/></p>
<ul>
<li>Demonstrate the seriousness of the issue.</li>
<li>Give real-world experience of the problem as encountered in
<a href="http://boost.org">Boost</a>.</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>
<li>Present the experience of a compiler writer who implemented the
suggested resolution in <a href=
"http://clang.llvm.org/">clang</a>.</li>
</ul>
<p><a href="#Problem">Problem</a><br/>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#TrivialExample">Trivial
Example</a><br/>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Background">Background</a><br/>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#TheProblemInDetail">The Problem
in Detail</a><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href=
"#AsRelatesToTR1result_of">As Relates to TR1
<code>result_of</code></a><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href=
"#AsRelatesToCpp0xresult_of">As Relates to C++0x
<code>result_of</code></a><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href=
"#TimingIsEverything">Timing Is Everything</a><br/>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#AMoreRealisticExample">A More
Realistic Example</a><br/>
&nbsp;&nbsp;&nbsp;&nbsp;<a href=
"#TheImplicationsForGenericCode">The Implications for Generic
Code</a><br/>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#FieldExperienceBoost">Field
Experience: Boost</a><br/>
<a href="#Solution">Solution</a><br/>
&nbsp;&nbsp;&nbsp;&nbsp;<a href=
"#Solution_Notes">Notes About This Proposed
Solution</a><br/>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ProposedResolution">Proposed
Resolution</a><br/>
&nbsp;&nbsp;&nbsp;&nbsp;<a href=
"#OptionsConsideredAndDismissed">Options Considered and
Dismissed</a><br/>
&nbsp;&nbsp;&nbsp;&nbsp;<a href=
"#ImplementationExperience">Implementation Experience</a><br/>
<a href="#Acknowledgements">Acknowledgements</a><br/>
<a href="#AppendixA">Appendix A: Source Code for a Realistic
Example</a><br/></p>
<h2><a name="Problem" id="Problem">Problem</a></h2>
<p>The most common intended use of <code>decltype</code> is as the
return type of a function template, but it behaves differently than
just writing the type directly. From rationales given in the papers
that introduced <code>decltype</code> (<a href=
"http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1978.pdf">N1978</a>)
and <code>result_of</code> (<a href=
"http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1454.html">N1454</a>,
<a href=
"http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2194.pdf">
N2194</a>), it is clear that this equivalence was expected to hold.
<sup>[<a name="ftn1" href="#ftn.ftn1" id="ftn1">1</a>]</sup> That
fact that it does not causes code to break.</p>
<h3><a name="TrivialExample" id="TrivialExample">Trivial
Example</a></h3>
<p>Here is a simple program that demonstrates the problem:</p>
<blockquote>
<pre>
<code>
template&lt;class T&gt; struct S;

template&lt;class X, class Y&gt; struct pair {};

template&lt;class T&gt; S&lt;T&gt; wrap(T) { return 0; }

template&lt;class T&gt;
struct S
{
    S(int = 0) {}

    decltype(wrap(pair&lt;T,T&gt;())) foo() { return 0; } // ERROR

    S&lt;pair&lt;T,T&gt; &gt; bar() { return 0; }               // OK
};

S&lt;int&gt; s;
</code>
</pre></blockquote>
<p>The member functions <code>S::foo</code> and <code>S::bar</code>
should be equivalent. However, the decades-old rule (from 5.2.2
[expr.call]) that requires the completeness of the type of the
expression <code>wrap(pair&lt;T,T&gt;())</code>, used in the
<code>decltype()</code> in the declaration of
<code>S::foo()</code>, still applies (even though the old
motivations for type completeness---namely the need to allocate
storage for the prvalue temporary and the need to consider invoking
the type's destructor for that temporary---do not exist in this new
context). This sets off a cascade of template instantiations that
runs the compiler out of memory (tested on MSVC 10 and Comeau
Online as of 1/6/2011). The declaration of <code>S::bar</code> does
not. The implications for new code using <code>decltype</code> and,
by extension, old code using TR1's <code>result_of</code> are dire
and cannot be worked around.</p>
<h3><a name="Background" id="Background">Background</a></h3>
<p>TR1 introduced the <code>result_of</code> facility as a way for
generic code to compute the return type of any callable. It is
designed to work even with callables whose return types depend on
their argument types in non-trivial ways. To handle this case in
the absence of <code>decltype</code>, TR1's <code>result_of</code>
resorted to an idiom: a nested result template that
<code>result_of</code> could use to perform the computation. This
meant extra work for authors of function objects, and could be
considered a necessary evil in C++03. TR1's <code>result_of</code>
was explicitly designed as a bridge to the coming
<code>decltype</code> version, which would eliminate the need for
this extra work.</p>
<p><code>decltype</code> was introduced in large part to ease the
declarations of functions whose return types depend on their
argument types in non-trivial ways. In fact, that was the only
rationale given for <code>decltype</code> in <a href=
"http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1978.pdf">
N1978</a> (Section 2.1). Regrettably, this is precisely the
situation in which the problem is most likely to occur.</p>
<p><a href=
"http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2194.pdf">
N2194</a> changed <code>result_of</code> to use
<code>decltype</code>, obviating the need for nested result
templates. <code>decltype</code> is a step forward for
<code>result_of</code> in terms of usability. Early industry
experience, however, has shown that this transition is
problematic.</p>
<h3><a name="TheProblemInDetail" id="TheProblemInDetail">The
Problem in Detail</a></h3>
<p>The problem has to do with templates, instances of which can be
mentioned in code without causing their instantiation. For
instance:</p>
<blockquote>
<pre>
<code>
template&lt;class T&gt; foo { };
typedef foo&lt;int&gt; foo_int; // foo&lt;int&gt; only mentioned here
foo_int f;                // foo&lt;int&gt; instantiated here
                          // because the size &amp; alignment requirements
                          // of foo&lt;int&gt; are needed because storage for
                          // a foo&lt;int&gt; must be allocated; and because
                          // a  default constructor of foo&lt;int&gt; might
                          // be non-trivial (and if so needs
                          // to be called implicitly);
                          // and because the destructor of foo&lt;int&gt; might
                          // be non-trivial (and if so needs to be called
                          // implicitly at the end of the lifetime of f).
</code>
</pre></blockquote>
<h4><a name="AsRelatesToTR1result_of" id=
"AsRelatesToTR1result_of">As Relates to TR1
<code>result_of</code></a></h4>
<p>The old TR1 <code>result_of</code> implementation works with
nested result templates that expose the return type as a nested
typedef:</p>
<blockquote>
<pre>
<code>
struct make_foo
{
    template&lt;class Sig&gt; struct result;

    template&lt;typename This, typename T&gt;
    struct result&lt;This(T)&gt;
    {
        typedef foo&lt;T&gt; type; // foo&lt;T&gt; mentioned here
    };

    template&lt;class T&gt;
    foo&lt;T&gt; operator()(T t) // foo&lt;T&gt; instantiated at call site
    {
        return foo&lt;T&gt;();
    }
};
</code>
</pre></blockquote>
<p>Notice in the above code that within the nested result template,
<code>foo&lt;T&gt;</code> is only mentioned, and hence is not
instantiated. Only when <code>foo::operator()</code> is actually
called is <code>foo&lt;T&gt;</code> required to be complete. It
follows that in TR1, the following does not cause any instantiation
of <code>foo</code>:</p>
<blockquote>
<pre>
<code>
// In TR1, foo&lt;int&gt; is not instantiated:
typedef std::tr1::result_of&lt;make_foo(int)&gt;::type foo_int;
</code>
</pre></blockquote>
<h4><a name="AsRelatesToCpp0xresult_of" id=
"AsRelatesToCpp0xresult_of">As Relates to C++0x
<code>result_of</code></a></h4>
<p>The C++0x version of <code>result_of</code> uses
<code>decltype</code> to compute return types, eliminating the need
for nested result templates. The following line of C++0x code:</p>
<blockquote>
<pre>
<code>
typedef std::result_of&lt;make_foo(int)&gt;::type foo_int;
</code>
</pre></blockquote>
<p>is roughly equivalent to<sup>[<a name="ftn2" href="#ftn.ftn2"
id="ftn2">2</a>]</sup>:</p>
<blockquote>
<pre>
<code>
typedef decltype(make_foo()(int())) foo_int;
</code>
</pre></blockquote>
<p>The problem is that function call expressions require their
return types to be complete. As a consequence, the above use of
<code>result_of</code> now causes an instantiation of
<code>foo&lt;int&gt;</code>, whereas in TR1 it did not.</p>
<h4><a name="TimingIsEverything" id="TimingIsEverything">Timing is
Everything</a></h4>
<p>Why should we be concerned about instantiating a template
eagerly when presumably we're going to instantiate the template
anyway at some other point? By causing an eager template
instantiation, we create the potential for an infinite series of
cascading template instantiations that causes compilation to fail
where formerly it succeeded. This happens in code where
<code>result_of</code> is used to compute the return type of a
member function of a class template and the resulting type is
itself an instance of that class template, as happened with the
simple example given above.</p>
<h3><a name="AMoreRealisticExample" id="AMoreRealisticExample">A
More Realistic Example</a></h3>
<p>The code above is awkward and unlikely. <a href=
"#AppendixA">Appendix A</a> presents a more realistic example. It
is the skeleton of a very simple library for lazy expression
evaluation using <a href=
"http://en.wikipedia.org/wiki/Expression_templates">expression
templates</a>.</p>
<p>Expression templates are fairly mainstream technique used in
high-performance libraries like <a href=
"http://oonumerics.org/blitz/">Blitz++</a> and in domain-specific
libraries like <a href=
"http://boost.org/libs/lambda">Boost.Lambda</a> and <a href=
"http://boost.org/libs/spirit">Boost.Spirit</a>. It makes use of
overloaded operators that, rather than eagerly evaluate their
results, instead build a tree representing the expression so that
it can be evaluated later.</p>
<p><a href="#AppendixA">Appendix A</a> presents a very simple
expression template library implemented in a straight-forward
manner. Nodes in the expression tree are represented by instances
of the <code>Expr</code> template. New nodes are created by
operator overloads defined as members of <code>Expr</code>. The
return types of the operator overloads are computed using
<code>result_of</code> and the <code>MakeExpr</code> function
object. With the TR1-version of <code>result_of</code>, everything
works. With the <code>decltype</code> version it doesn't; that is,
when <code>BUGBUG</code> is defined, the code in <a href=
"#AppendixA">Appendix A</a> causes Visual C++ 10 and Comeau's
online compiler to recursively instantiate an infinite number of
templates.</p>
<h3><a name="TheImplicationsForGenericCode" id=
"TheImplicationsForGenericCode">The Implications for Generic
Code</a></h3>
<p>The implications of US22/DE9 are plain: <code>decltype</code>,
and hence <code>std::result_of</code>, cannot safely be used in
class templates to compute the return types of member functions.
Note that the primary mandate of both <code>decltype</code> and
<code>std::result_of</code> is to make it easy to compute return
types in generic code. Due to the context-insensitivity of the old
type-completeness rule in 5.2.2 [expr.call], <code>decltype</code>
and <code>std::result_of</code> both fail their primary
mandate.</p>
<p>The other implication is that some valid C++03 designs that are
currently making use of <code>std::tr1::result_of</code> must
eschew <code>std::result_of</code> for fear of being bitten by this
problem. This will lead to a bifurcation in the library space: some
code will move to <code>std::result_of</code>, and some will stay
with <code>std::tr1::result_of</code>. Those libraries that stick
with <code>tr1::result_of</code> impose the TR1
<code>result_of</code> protocol on all its users. And as TR1 is not
a standard, there is no guarantee that
<code>std::tr1::result_of</code> will continue to be available.</p>
<p>Note that at least one major vendor currently shipping both
<code>std::result_of</code> and <code>std::tr1::result_of</code>
simply share the same <code>decltype</code>-based
implementation<sup>[<a name="ftn3" href="#ftn.ftn3" id=
"ftn3">3</a>]</sup>, so this problem can bite even those users that
choose to stick with <code>std::tr1::result_of</code>.</p>
<h3><a name="FieldExperienceBoost" id="FieldExperienceBoost">Field
Experience: Boost</a></h3>
<p>This is not some dreamed up and unlikely scenario. The problem
was discovered in the field by porting
<code>boost::result_of</code> to use <code>decltype</code> on those
compilers that support it. When this change was made, the tests of
one important foundational library, <a href=
"http://boost.org/libs/proto">Boost.Proto</a>, and all the
libraries that depend on it (<a href=
"http://boost.org/libs/spirit">Boost.Spirit</a>, <a href=
"http://boost.org/libs/xpressive">Boost.Xpressive</a>) began
failing.</p>
<p>To work around the problem, Boost has had to ship two versions
of <code>result_of</code>: one that uses the TR1 protocol
(<code>boost::tr1_result_of</code>), and one that uses
<code>decltype</code> if it's available
(<code>boost::result_of</code>). <a href=
"http://boost.org/libs/proto">Boost.Proto</a> had to be changed to
use <code>boost::tr1_result_of</code> in all places where it was
determined this problem could crop up. And at the time of writing
(1/6/2011), the use of <code>decltype</code> in
<code>boost::result_of</code> is turned off by default until this
issue is resolved.</p>
<p>This has downstream effects: all Boost users are still bound to
use the TR1 protocol for their function objects even when
<code>decltype</code> is available. We are not seeing the much
hoped-for reduction of meta-programming promised by
<code>decltype</code> and <code>std::result_of</code>. Said Doug
Gregor, author of the TR1 <code>result_of</code> proposals, in a
private exchange:</p>
<blockquote>It's a personal embarrassment, because
<code>result_of</code> was meant to be a bridge to
<code>decltype</code>, and it's completely broken by this.
[&hellip;] It's definitely a problem that return-type-computing
metaprograms will be forced to live on, when we tried so hard to
kill them with <code>decltype</code>. Will <code>decltype</code>
even get used?</blockquote>
<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>
    This change makes it so that, when the expression in a
    <var>decltype-specifier</var> is a function call expression, and when the
    return type of the selected function is a class type,
</p>

    <ul>
        <li>the type is not required to be complete and </li>

        <li>a temporary object is not introduced for the return
        value (and as a result, storage is not allocated for the prvalue and a
        destructor is not invoked).</li>
    </ul>

<p>
Both changes occur in section 5.2.2 [expr.call] and reference 12.2
[class.temporary]. 12.2 p1 is modified to clarify that, wherever a
temporary is introduced in an unevaluated context, semantic constraints
are checked. 
</p>

<div>
Note that sub-expressions (e.g. function calls used as call arguments) are
not affected.   Also, unevaluated operands outside of a <tt>decltype</tt>
are not affected.
For example, the following code was ill-formed in C++03 and will remain
ill-formed:<div class="ex">
<pre>struct A g();
char f(struct B);
int f(...);

unsigned long z = sizeof(f(g())); <span class="cm">Error: return type of <tt>g()</tt> must be</span>
                                  <span class="cm">complete.</span></pre>
</div>

</div>

<p>
This behavior must be maintained because the outcome of overload
resolution depends on conversions and therefore type-completion.
</p>

<p>
If the user wants type completion, they can wrap the expression
in a call to an "identity" function template. (See <tt>i()</tt> in the
example in the proposed wording below.  This resolves the issue raised in
c++std-core-16953.)
</p>

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


<div id="decltype_and_call_exprs">
    <ul>

    <li>
        <p>Change
        3.10 basic.lval
        <span>p</span>4
        as indicated:
        </p>
        <blockquote>
            <ol start="4">
            <li>
            Class prvalues can have cv-qualified types; non-class
            prvalues always have cv-unqualified types.

            <ins>Unless otherwise indicated (5.2.2),</ins>

            <del>P</del><ins>p</ins>rvalues
            shall always have complete types or the void type; in
            addition to these types, glvalues can also have
            incomplete types.


            </li>
            </ol>
        </blockquote>
    </li>



    <li>
      <p>Change
      5.2.2 expr.call
      <span>p</span>3
      as indicated:
      </p>
      <blockquote>
        <ol start="3">
        <li>
        If the postfix-expression designates a destructor
        (12.4), the type of the function call expression is
        void; otherwise, the type of the function call
        expression is the return type of the statically chosen
        function (i.e., ignoring the virtual keyword), even if
        the type of the function actually called is different.
        This type shall be

        a<ins>n</ins> <del>complete</del> object type, a reference

        type or the type void.
        </li>
        </ol>
      </blockquote>
    </li>

    <li>
        <p>Append a new paragraph to the end of
        5.2.2 expr.call:
        </p>
        <blockquote>
          <ol start="10">

            <li>
            A function call is an lvalue if the result type is an lvalue
            reference type or an rvalue reference to function type, an
            xvalue if the result type is an rvalue reference to object
            type, and a prvalue otherwise.
            </li>

            <li>

            <ins>If a function call is a prvalue:

              <ul>

                <li>
                If the function call is not the <var>expression</var> of
                a <var>decltype-specifier</var>,

               a temporary object may be introduced for the prvalue (12.2,
               6.6.3).  If introduced, storage for the temporary is
                 allocated in the context of the function call.
                </li>

                <li>
                Otherwise (i.e., the function call is the
                <var>expression</var> of a <var>decltype-specifier</var>),
                a temporary object is not introduced for the prvalue.  (As
                a result, storage is not allocated for the prvalue and it
                is not destroyed.) The type of the prvalue may be
                incomplete.  

                <div class="note">
                  Consequently, a class type is not instantiated as a
                  result of being the type of a function call in this
                  context.  This is true regardless of whether the
                  expression uses function call notation or operator
                  notation (13.3.1.2 over.match.oper).
                </div>

                </li>



              </ul>
            </ins>
            </li>

            </ol>
        </blockquote>
    </li>

    <li>
        <p>Append a new paragraph to the end of
        7.1.6.2 dcl.type.simple:
        </p>
        <blockquote>
            <ol start="5">
            <li>

            <ins>
                <div class="note">
                    In the case where the <var>expression</var> of a
                    <var>decltype-specifier</var> is a function call and
                    the return type of the function is a class type, a
                    special rule (5.2.2) ensures that the return type is
                    not required to be complete (as it would be if the
                    call appears in a sub-expression or outside of a
                    <var>decltype-specifier</var>).  In this context,

                    the common purpose of writing the expression is merely
                    to refer to its type.  In that sense, a
                    <var>decltype-specifier</var> is analogous to a use of
                    a <var>typedef-name</var>, so the usual reasons
                    for requiring a complete type do not apply.   In
                    particular, it is not necessary to allocate storage
                    for a temporary object, and typically, it is not
                    necessary to enforce the semantic constraints
                    associated with invoking the type's destructor.  

        <div class="ex">
          <pre><ins>template&lt;class T&gt; struct A { ~A() = delete; };

template&lt;class T&gt; auto h()
    -&gt; A&lt;T&gt;;

template&lt;class T&gt; auto i(T) <div class="cm">identity</div>
    -&gt; T;

template&lt;class T&gt; auto f(T) <div class="cm">#1</div>

    -&gt; decltype(i(h&lt;T&gt;())); <div class="cm">forces completion of <tt>A&lt;T&gt;</tt> and implicitly uses <tt>A&lt;T&gt;::~A()</tt> for the</div>
                            <div class="cm">temporary introduced by the use of <tt>h()</tt>.  (A temporary is not </div>
                            <div class="cm">introduced as a result of the use of <tt>i()</tt>).</div>

template&lt;class T&gt; auto f(T) <div class="cm">#2</div>
    -&gt; void;

auto g() -&gt; void {
    f(42); <div class="cm">Ok. (#1 is not a viable candidate: type deduction fails (14.8.2) because</div>
           <div class="cm"><tt>A&lt;int&gt;::~A()</tt> is implicitly used in its decltype-specifier)</div>
}


template&lt;class T&gt; auto q( T )
  -&gt; decltype(h&lt;T&gt;());  <div class="cm">Does not force completion of <tt>A&lt;T&gt;</tt>;</div>
                        <div class="cm"><tt>A&lt;T&gt;::~A()</tt> is not implicitly used within the</div>
                        <div class="cm">context of this <var>decltype-specifier</var>.</div>

void r() {
    q(42); <div class="cm">Error: deduction against q succeeds, so overload resolution</div>
           <div class="cm">selects the specialization ''<tt>q(T)-&gt;decltype(h&lt;T&gt;()) [with T=int]</tt>''.</div>
           <div class="cm">The return type is <tt>A&lt;int&gt;</tt>, so a temporary is</div>
           <div class="cm">introduced and its destructor is used, so the program</div>
           <div class="cm">ill-formed.</div>

}</ins></pre>
        </div>

                </div>
            </ins>

            </li>
            </ol>
        </blockquote>
    </li>


    <li>
      <p>Change
      12.2 class.temporary
      <span>p</span>1
      as indicated:
      </p>
      <blockquote>
        <ol start="1">
        <li>
        Temporaries of class type are created in various contexts:
        binding a reference to a prvalue (8.5.3), returning a
        prvalue (6.6.3), a conversion that creates a prvalue (4.1,
        5.2.9, 5.2.11, 5.4), throwing an exception (15.1), entering
        a handler (15.3), and in some initializations (8.5).

        <div class="note">
         the lifetime of exception objects is
            described in 15.1.
          </div>

        Even when the creation of the temporary object is

        <ins>unevaluated (Clause 5) or otherwise</ins>

        avoided (12.8), all the semantic restrictions shall be respected
        as if the temporary object had been created

        <ins>and later destroyed</ins>. 

        <div class="note">
            Even if

            <del>the copy/move constructor is not called</del>

            <ins>there is no call to the destructor or copy/move
            constructor</ins>,

            all the semantic restrictions, such as accessibility
          (Clause 11) <ins>and <tt>=delete</tt> (8.4.3)</ins>, shall be
          satisfied.
        </div>


        </li>
        </ol>
      </blockquote>
    <p>
      [Drafting note: 12.2 class.temporary p3 is unchanged.  In drafts
       of this proposal, it was preceded by an exception for the
      <tt>decltype</tt> case.  But p3 applies only ``When an
      implementation introduces a temporary object'', and the change
      proposed for 5.2.2 above ensures that a temporary is <em>not</em>
      introduced for the <var>expression</var> of a
      <var>decltype-specifier</var>, so the destructor
      call is naturally suppressed.]
    </p>

    </li>
    </ul>


</div>


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

<div>
Jason Merrill pointed out that the wording change proposed above
introduces a very special case,  so we considered a more general rule: in
this alternative, the type of a function return value is required to be
complete only if

<ul>
    <li>
    the call is potentially evaluated or
    </li>
    <li>
    the return value (a prvalue) is converted.
    </li>
</ul>

(An identity-converted value can be regarded as "converted", since some
types are not copyable/movable.)
</div>

<div>
For reasons mentioned above (see the <tt>sizeof</tt> example), it's
important to allow type-completion on any function return value that is
converted.  So to see where this alternative rule would prevent
type-completion we should consider operands that are <em>not</em>
converted.  We find them by elimination:

    <ul>
        <li>We can rule out every operand that is required to
        be of scalar type because that would imply a user-defined
        conversion to the scalar type.</li>

        <li>The Lvalue-to-rvalue conversion is always applied to operands
        2 and 3 of the conditional operator even if they are of identical
        class type and have the same value category.</li>

        <li>The address operator does not apply because it cannot have a
        prvalue operand.</li>

        <li><tt>sizeof</tt> and <tt>alignof</tt> always need a complete
        type.</li>

        <li>Cast operators seem pointless to even contemplate for
        <tt>decltype</tt> purposes.</li>

        <li><tt>typeid</tt> requires a complete type to see whether its
        operand is of polymorphic type.</li>
    </ul>

So we are left with:

<ul>
    <li>a full-expression;</li>

    <li>the left operand to comma;</li>

    <li>the right operand to comma;</li>

    <li>the <var>expression</var> in a <var>noexcept-expression</var>.</li>
</ul>


</div>

<p>
For the purpose of writing a <var>decltype-specifier</var> it seems
pointless to use a comma-operator as the top-level operation since the
type of the left operand does not affect the type of the full-expression.

In the case of a <var>noexcept-expression</var>, the implicit invocation
of the return type's destructor on the temporary is probably desired
because it might throw, in which case the <var>noexcept-expression</var>
is would be <tt>false</tt>.  By contrast, an implicit destructor call
would not affect the type of a <var>decltype-specifier</var>.
</p>


<h3><a name="ImplementationExperience" id=
"ImplementationExperience">Implementation Experience</a></h3>
<p>We have implemented our proposed resolution for the Clang compiler.
The implementation itself is simple and straightforward, suppressing
the type-completion and temporary-construction logic when building
calls at the top level of a <code>decltype</code> expression. We tested
the implementation against Boost's Proto library (configured to use
<code>decltype</code> via <code>result_of</code>), confirming that the
proposed resolution does in fact address the issues seen in Boost and
does not appear to cause any breakage. We do not anticipate that other
implementors will have any difficulty implementing this change.</p>

<h2><a name="Acknowledgements" id="Acknowledgements">Acknowledgements</a></h2>
<p>
   Many thanks to Jason Merrill, Daniel Krügler, Steve Adamczyk, and Jens
   Maurer for early reviews and helpful comments.
</p>

<hr/>
<h3><a name="AppendixA" id="AppendixA">Appendix A: Source Code for
a Realistic Example</a></h3>
<p>The following code demonstrates how reasonable and valid code
using TR1 <code>result_of</code> can stop working when
<code>result_of</code> is switched to use <code>decltype</code>. It
is the skeleton of a simple expression template library. An
expression is captured in a tree of <code>Expr</code> objects,
built by operator overloads defined as member functions of the
<code>Expr</code> template. It makes idiomatic use of a
<code>MakeExpr</code> function object for computing return types.
Porting this code to C++0x's <code>result_of</code> will break this
perfectly valid and reasonable design.</p>
<blockquote>
<pre>
<code>
// Uncomment this for a wild time:
//#define BUGBUG

// A simplified result_of implementation.
// If BUGBUG is defined, it uses decltype.
// Otherwise, it uses the TR1 result_of
// protocol.
template&lt;typename Sig&gt;
struct result_of;

#ifdef BUGBUG
  template&lt;typename T&gt; T&amp; declvar();

  // use decltype
  template&lt;typename Fun, typename T&gt;
  struct result_of&lt;Fun(T)&gt;
  {
    typedef decltype(declvar&lt;Fun&gt;()(declvar&lt;T&gt;())) type;
  };

  template&lt;typename Fun, typename T, typename U&gt;
  struct result_of&lt;Fun(T, U)&gt;
  {
    typedef decltype(declvar&lt;Fun&gt;()(declvar&lt;T&gt;(), declvar&lt;U&gt;())) type;
  };
#else
  // use TR1 protocol
  template&lt;typename Fun, typename T&gt;
  struct result_of&lt;Fun(T)&gt;
    : Fun::template result&lt;Fun(T)&gt;
  {};

  template&lt;typename Fun, typename T, typename U&gt;
  struct result_of&lt;Fun(T, U)&gt;
    : Fun::template result&lt;Fun(T, U)&gt;
  {};
#endif

// simple tuple type
template&lt;typename A0 = void, typename A1 = void, typename A2 = void&gt;
struct tuple;

template&lt;typename A0&gt;
struct tuple&lt;A0, void, void&gt;
{
  A0 a0_;
  tuple(A0 const &amp;a0) : a0_(a0) {}
};

template&lt;typename A0, typename A1&gt;
struct tuple&lt;A0, A1&gt;
{
  A0 a0_;
  A1 a1_;
  tuple(A0 const &amp;a0, A1 const &amp; a1) : a0_(a0), a1_(a1) {}
};

// A node in an expression tree
template&lt;class Tag, class Args&gt; // Args is a tuple.
struct Expr;

// A function object that builds expression nodes
template&lt;class Tag&gt;
struct MakeExpr
{
  template&lt;class Sig&gt;
  struct result;

  template&lt;class This, class T&gt;
  struct result&lt;This(T)&gt;
  {
    typedef Expr&lt;Tag, tuple&lt;T&gt; &gt; type;
  };

  template&lt;class This, class T, class U&gt;
  struct result&lt;This(T, U)&gt;
  {
    typedef Expr&lt;Tag, tuple&lt;T, U&gt; &gt; type;
  };

  template&lt;class T&gt;
  Expr&lt;Tag, tuple&lt;T&gt; &gt; operator()(T const &amp; t) const
  {
    return Expr&lt;Tag, tuple&lt;T&gt; &gt;(tuple&lt;T&gt;(t));
  }

  template&lt;class T, typename U&gt;
  Expr&lt;Tag, tuple&lt;T, U&gt; &gt; operator()(T const &amp; t, U const &amp; u) const
  {
    return Expr&lt;Tag, tuple&lt;T, U&gt; &gt;(tuple&lt;T, U&gt;(t, u));
  }
};

// Here are tag types that encode in an expression node
// what operation created the node.
struct Terminal;
struct BinaryPlus;
struct FunctionCall;

typedef MakeExpr&lt;Terminal&gt;      MakeTerminal;
typedef MakeExpr&lt;BinaryPlus&gt;    MakeBinaryPlus;
typedef MakeExpr&lt;FunctionCall&gt;  MakeFunctionCall;

template&lt;class Tag, class Args&gt;
struct Expr
{
  Args args_;
  explicit Expr(Args const &amp; t) : args_(t) {}

  // An overloaded operator+ that creates a binary plus node
  template&lt;typename RTag, typename RArgs&gt;
  typename result_of&lt;MakeBinaryPlus(Expr, Expr&lt;RTag, RArgs&gt;)&gt;::type
  operator+(Expr&lt;RTag, RArgs&gt; const &amp;right) const
  {
    return MakeBinaryPlus()(*this, right);
  }

  // An overloaded function call operator that creates a unary
  // function call node
  typename result_of&lt;MakeFunctionCall(Expr)&gt;::type
  operator()() const
  {
    return MakeFunctionCall()(*this);
  }
};

int main()
{
  // This is a terminal in an expression tree
  auto i = MakeTerminal()(42);

  i + i; // OK, this creates a binary plus node.

  i(); // OK, this creates a unary function-call node
}
</code>
</pre></blockquote>
<hr/>
<div style="font-size:small">
<p><sup>[<a name="ftn.ftn1" href="#ftn1" id="ftn.ftn1">1</a>]</sup>
Below are quotes from the various proposals showing that
<code>decltype</code> and <code>result_of</code> were intended to
solve problems with function return type declarations, and that the
intention was that the <code>decltype</code> formulation of return
types was intended to be functionally equivalent to just writing
the type directly.</p>
<dl>
<dt>From <a href=
"http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1454.html">
N1454</a></dt>
<dd>"result_of is intended to act as a bridge from the function
objects of C++98 to more powerful function objects as used in
current binding and composition libraries. This bridge provides
both forward compatibility, allowing C++02 code to derive benefits
from future C++ revisions without modification"</dd>
<dt>From <a href=
"http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1978.pdf">
N1978</a></dt>
<dd>"2.1 Why decltype is crucial: The return type of a generic
function often depends on the types of the arguments. In some cases
the dependency can be expressed within the current language. [...]
In other cases this is not as easy, or even possible."</dd>
<dt>From <a href=
"http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2194.pdf">
N2194</a></dt>
<dd>"In particular the result_of hook---which is the only aspect of
the Standard Library that this document changes&mdash;was designed
with forward-compatibility in mind [1]. result_of currently says
that implementations are permitted to get the return type of a
particular function call by any means possible, so long as they get
the answer right; if they cannot do so, result_of specifies a
protocol that the implementation should follow to extract the
return type from library- and user-provided information. With
decltype, every implementation can get the answer right, so we need
only eliminate the weasel-wording result_of currently uses. We note
that a C++0x result_of meets the requirements of a TR1
result_of."</dd>
</dl>
<p><sup>[<a name="ftn.ftn2" href="#ftn2" id=
"ftn.ftn2">2</a>]</sup>This ignores the use of tricks to avoid the
default-constructability requirements imposed here, but
that&rsquo;s not relevant to this discussion.</p>
<p><sup>[<a name="ftn.ftn3" href="#ftn3" id=
"ftn.ftn3">3</a>]</sup>Microsoft Visual Studio C++ 10.0</p>
</div>
</body>
</html>
