<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 1255: declval should be added to the library</title>
<meta property="og:title" content="Issue 1255: declval should be added to the library">
<meta property="og:description" content="C++ library issue. Status: C++11">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue1255.html">
<meta property="og:type" content="website">
<meta property="og:image" content="http://cplusplus.github.io/LWG/images/cpp_logo.png">
<meta property="og:image:alt" content="C++ logo">
<style>
  p {text-align:justify}
  li {text-align:justify}
  pre code.backtick::before { content: "`" }
  pre code.backtick::after { content: "`" }
  blockquote.note
  {
    background-color:#E0E0E0;
    padding-left: 15px;
    padding-right: 15px;
    padding-top: 1px;
    padding-bottom: 1px;
  }
  ins {background-color:#A0FFA0}
  del {background-color:#FFA0A0}
  table.issues-index { border: 1px solid; border-collapse: collapse; }
  table.issues-index th { text-align: center; padding: 4px; border: 1px solid; }
  table.issues-index td { padding: 4px; border: 1px solid; }
  table.issues-index td:nth-child(1) { text-align: right; }
  table.issues-index td:nth-child(2) { text-align: left; }
  table.issues-index td:nth-child(3) { text-align: left; }
  table.issues-index td:nth-child(4) { text-align: left; }
  table.issues-index td:nth-child(5) { text-align: center; }
  table.issues-index td:nth-child(6) { text-align: center; }
  table.issues-index td:nth-child(7) { text-align: left; }
  table.issues-index td:nth-child(5) span.no-pr { color: red; }
  @media (prefers-color-scheme: dark) {
     html {
        color: #ddd;
        background-color: black;
     }
     ins {
        background-color: #225522
     }
     del {
        background-color: #662222
     }
     a {
        color: #6af
     }
     a:visited {
        color: #6af
     }
     blockquote.note
     {
        background-color: rgba(255, 255, 255, .10)
     }
  }
</style>
</head>
<body>
<hr>
<p><em>This page is a snapshot from the LWG issues list, see the <a href="lwg-active.html">Library Active Issues List</a> for more information and the meaning of <a href="lwg-active.html#C++11">C++11</a> status.</em></p>
<h3 id="1255"><a href="lwg-defects.html#1255">1255</a>. <code>declval</code> should be added to the library</h3>
<p><b>Section:</b> 22.2 <a href="https://wg21.link/utility">[utility]</a> <b>Status:</b> <a href="lwg-active.html#C++11">C++11</a>
 <b>Submitter:</b> Daniel Kr&uuml;gler <b>Opened:</b> 2009-11-03 <b>Last modified:</b> 2016-01-28</p>
<p><b>Priority: </b>Not Prioritized
</p>
<p><b>View all other</b> <a href="lwg-index.html#utility">issues</a> in [utility].</p>
<p><b>View all issues with</b> <a href="lwg-status.html#C++11">C++11</a> status.</p>
<p><b>Discussion:</b></p>
<p>
During the Santa Cruz meeting it was decided to split off the provision
of the library utility <code>value()</code> proposed in 
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2979.html">N2979</a>
from the concrete request of the
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2939.html#UK300">UK 300</a>
comment.
The provision of a new library component that allows the production of
values in unevaluated expressions is considered as important
to realize constrained templates in C++0x where concepts are not
available.
</p>

<p>
The following proposed resolution is an improvement over that suggested in
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2958.html">N2958</a>,
because the proposed component can now be defined without loss of
general usefulness and any <i>use</i> by user-code will make the program ill-formed.
A possible prototype implementation that satisfies the core language
requirements can be written as:
</p>

<blockquote><pre>
template&lt;class T&gt;
  struct declval_protector {
    static const bool stop = false;
    static typename std::add_rvalue_reference&lt;T&gt;::type delegate(); <span style="color:#C80000">// undefined</span>
  };

template&lt;class T&gt;
typename std::add_rvalue_reference&lt;T&gt;::type declval() {
  static_assert(declval_protector&lt;T&gt;::stop, "declval() must not be used!");
  return declval_protector&lt;T&gt;::delegate();
}
</pre></blockquote>

<p>
Further-on the earlier suggested name <code>value()</code> has been changed to <code>declval()</code>
after discussions with committee members.
</p>

<p>
Finally the suggestion shown below demonstrates that it can simplify
existing standard wording by directly using it in the library
specification, and that it also improves an overlooked corner case for
<code>common_type</code> by adding support for <code>cv void</code>.
</p>

<p><i>[
2009-11-19 Moved to Tentatively Ready after 6 positive votes on c++std-lib.
]</i></p>



<p id="res-1255"><b>Proposed resolution:</b></p>
<p><i>[
The proposed resolution has been updated to
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n3000.pdf">N3000</a>
numbering and wording
]</i></p>


<ol>
<li>
<p>
Change 22.2 <a href="https://wg21.link/utility">[utility]</a>, header <code>&lt;utility&gt;</code> synopsis
as indicated:
</p>

<blockquote><pre>
// 20.3.3, forward/move:
template &lt;class T&gt; struct identity;
template &lt;class T, class U&gt; T&amp;&amp; forward(U&amp;&amp;);
template &lt;class T&gt; typename remove_reference&lt;T&gt;::type&amp;&amp; move(T&amp;&amp;);

<ins>// 20.3.4, declval:</ins>
<ins>template &lt;class T&gt; typename add_rvalue_reference&lt;T&gt;::type declval(); // as unevaluated operand</ins>
</pre></blockquote>
</li>

<li>
<p>
Immediately after the current section 22.2.4 <a href="https://wg21.link/forward">[forward]</a> insert a
new section:
</p>
<p>
<ins>20.3.4 Function template declval [declval]</ins>
</p>
<p>
<ins>The library provides the function template <code>declval</code> to simplify
the definition of expressions which occur as
unevaluated operands (7 <a href="https://wg21.link/expr">[expr]</a>). The
template parameter <code>T</code> of <code>declval</code> may
be an incomplete type.</ins>
</p>

<pre>
<ins>template &lt;class T&gt; typename add_rvalue_reference&lt;T&gt;::type declval(); // as unevaluated operand</ins>
</pre>

<blockquote>
<p>
<ins><i>Remarks:</i> If this function is used according to 6.3 <a href="https://wg21.link/basic.def.odr">[basic.def.odr]</a>,
the program is ill-formed.</ins>
</p>

<p>
<ins>[<i>Example:</i></ins>
</p>

<blockquote><pre><ins>
template&lt;class To, class From&gt;
decltype(static_cast&lt;To&gt;(declval&lt;From&gt;())) convert(From&amp;&amp;);
</ins></pre></blockquote>

<p>
<ins>
declares a function template <code>convert</code>, which only participates in
overloading if the type <code>From</code> can be explicitly cast to type <code>To</code>.
For another example see class template <code>common_type</code>
(21.3.9.7 <a href="https://wg21.link/meta.trans.other">[meta.trans.other]</a>).
&mdash; <i>end example</i>]</ins>
</p>
</blockquote>

</li>

<li>
<p>
This bullet just makes clear that after applying 
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2984.htm">N2984</a>, 
the changes in 21.3.6.4 <a href="https://wg21.link/meta.unary.prop">[meta.unary.prop]</a>, before
table Type property queries should <em>not</em> use <code>declval</code>,
because the well-formedness requirement of the specification of
<code>is_constructible</code> would become more complicated, because we
would need to make sure that the expression <i>CE</i> is checked in an
unevaluated context.
</p>
</li>

<li>
<p>
Also 21.3.8 <a href="https://wg21.link/meta.rel">[meta.rel]</a>/4 is not modified similar to the previous bullet,
because with the stricter requirements of not using <code>declval()</code> the well-formedness condition
would be harder to specify. The following changes are only editorial ones (e.g.
the removal of the duplicate declaration of <code>create()</code>):
</p>

<blockquote>
<p>
Given the following function prototype:
</p>

<blockquote><pre>
template &lt;class T&gt;
  typename add_rvalue_reference&lt;T&gt;::type create();
</pre></blockquote>

<p>
the predicate condition for a template specialization
<code>is_convertible&lt;From, To&gt;</code> shall be satisfied if and only
if the return expression in the following code would be well-formed,
including any
implicit conversions to the return type of the function:
</p>

<blockquote><pre>
<del>template &lt;class T&gt;
typename add_rvalue_reference&lt;T&gt;::type create();</del>
To test() {
  return create&lt;From&gt;();
}
</pre></blockquote>
</blockquote>
</li>

<li>
<p>
Change the entry in column "Comments" for <code>common_type</code> in Table 51 &mdash;
Other transformations (21.3.9.7 <a href="https://wg21.link/meta.trans.other">[meta.trans.other]</a>):
</p>

<p><i>[
NB: This wording change extends the type domain of <code>common_type</code> for <code>cv
void =&gt; cv void</code> transformations and thus makes <code>common_type</code> usable for
all binary type combinations that are supported by <code>is_convertible</code>
]</i></p>


<blockquote><p>
The member typedef <code>type</code> shall be defined as set out below. All
types in the parameter pack <code>T</code> shall be complete <ins>or
(possibly cv-qualified) <code>void</code></ins>. A program may specialize
this trait if at least one template parameter in the specialization is a
user-defined type. [<i>Note:</i> Such specializations are needed when
only explicit conversions are desired among the template arguments.
&mdash; <i>end note</i>]
</p></blockquote>
</li>

<li>
<p>
Change 21.3.9.7 <a href="https://wg21.link/meta.trans.other">[meta.trans.other]</a>/3 as indicated:
</p>

<p><i>[
NB: This wording change is more than an editorial simplification of
the definition of <code>common_type</code>: It also extends its usefulness for <code>cv
void</code> types as outlined above
]</i></p>


<blockquote>
<p>
The nested typedef <code>common_type::type</code> shall be defined as follows:
</p>

<blockquote>
<p>
[..]
</p>
<pre>
template &lt;class T, class U&gt;
struct common_type&lt;T, U&gt; {
<del>private:
  static T&amp;&amp; __t();
  static U&amp;&amp; __u();
public:</del>
  typedef decltype(true ? <del>__t</del><ins>declval&lt;T&gt;</ins>() : <del>__u</del><ins>declval&lt;U&gt;</ins>()) type;
};
</pre>
</blockquote>
</blockquote>
</li>

<li>
<p>
Change 99 [func.ret]/1 as indicated
[<i>This part solves some main aspects of issue <a href="lwg-defects.html#1225" title="C++0x result_of issue  (Status: Resolved)">1225</a><sup><a href="https://cplusplus.github.io/LWG/issue1225" title="Latest snapshot">(i)</a></sup></i>]:
</p>

<blockquote><pre>
namespace std {
  template &lt;class&gt; class result_of; // undefined

  template &lt;class Fn, class... ArgTypes&gt;
  class result_of&lt;Fn(ArgTypes...)&gt; {
  public :
    <del>// types</del>
    typedef <del>see below</del><ins>decltype(declval&lt;Fn&gt;() ( declval&lt;ArgTypes&gt;()... ))</ins> type;
  };
}
</pre>
<p>
<del>1 Given an rvalue <code>fn</code> of type <code>Fn</code> and values <code>t1, t2, ..., tN</code> of
types <code>T1, T2, ..., TN</code> in <code>ArgTypes</code>,
respectively, the <code>type</code> member is the result type of the expression
<code>fn(t1, t2, ...,tN)</code>. The values <code>ti</code>
are lvalues when the corresponding type <code>Ti</code> is an lvalue-reference
type, and rvalues otherwise.</del>
</p>
</blockquote>
</li>
</ol>






</body>
</html>
