<?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" />
<meta name="generator" content="Docutils 0.3.10: http://docutils.sourceforge.net/" />
<title>Yet another type-trait: decay</title>
<meta name="author" content="Thorsten Ottosen" />
<meta name="date" content="2005-09-08" />
<style type="text/css">

/*
:Author: David Goodger
:Contact: goodger@users.sourceforge.net
:Date: $Date: 2005-09-25 17:49:54 +0200 (Sun, 25 Sep 2005) $
:Revision: $Revision: 3901 $
:Copyright: This stylesheet has been placed in the public domain.

Default cascading style sheet for the HTML output of Docutils.

See http://docutils.sf.net/docs/howto/html-stylesheets.html for how to
customize this style sheet.
*/

/* "! important" is used here to override other ``margin-top`` and
   ``margin-bottom`` styles that are later in the stylesheet or 
   more specific.  See http://www.w3.org/TR/CSS1#the-cascade */
.first {
  margin-top: 0 ! important }

.last, .with-subtitle {
  margin-bottom: 0 ! important }

.hidden {
  display: none }

a.toc-backref {
  text-decoration: none ;
  color: black }

blockquote.epigraph {
  margin: 2em 5em ; }

dl.docutils dd {
  margin-bottom: 0.5em }

/* Uncomment (and remove this text!) to get bold-faced definition list terms
dl.docutils dt {
  font-weight: bold }
*/

div.abstract {
  margin: 2em 5em }

div.abstract p.topic-title {
  font-weight: bold ;
  text-align: center }

div.admonition, div.attention, div.caution, div.danger, div.error,
div.hint, div.important, div.note, div.tip, div.warning {
  margin: 2em ;
  border: medium outset ;
  padding: 1em }

div.admonition p.admonition-title, div.hint p.admonition-title,
div.important p.admonition-title, div.note p.admonition-title,
div.tip p.admonition-title {
  font-weight: bold ;
  font-family: sans-serif }

div.attention p.admonition-title, div.caution p.admonition-title,
div.danger p.admonition-title, div.error p.admonition-title,
div.warning p.admonition-title {
  color: red ;
  font-weight: bold ;
  font-family: sans-serif }

/* Uncomment (and remove this text!) to get reduced vertical space in
   compound paragraphs.
div.compound .compound-first, div.compound .compound-middle {
  margin-bottom: 0.5em }

div.compound .compound-last, div.compound .compound-middle {
  margin-top: 0.5em }
*/

div.dedication {
  margin: 2em 5em ;
  text-align: center ;
  font-style: italic }

div.dedication p.topic-title {
  font-weight: bold ;
  font-style: normal }

div.figure {
  margin-left: 2em }

div.footer, div.header {
  clear: both;
  font-size: smaller }

div.line-block {
  display: block ;
  margin-top: 1em ;
  margin-bottom: 1em }

div.line-block div.line-block {
  margin-top: 0 ;
  margin-bottom: 0 ;
  margin-left: 1.5em }

div.sidebar {
  margin-left: 1em ;
  border: medium outset ;
  padding: 1em ;
  background-color: #ffffee ;
  width: 40% ;
  float: right ;
  clear: right }

div.sidebar p.rubric {
  font-family: sans-serif ;
  font-size: medium }

div.system-messages {
  margin: 5em }

div.system-messages h1 {
  color: red }

div.system-message {
  border: medium outset ;
  padding: 1em }

div.system-message p.system-message-title {
  color: red ;
  font-weight: bold }

div.topic {
  margin: 2em }

h1.section-subtitle, h2.section-subtitle, h3.section-subtitle,
h4.section-subtitle, h5.section-subtitle, h6.section-subtitle {
  margin-top: 0.4em }

h1.title {
  text-align: center }

h2.subtitle {
  text-align: center }

hr.docutils {
  width: 75% }

img.align-left {
  clear: left }

img.align-right {
  clear: right }

img.borderless {
  border: 0 }

ol.simple, ul.simple {
  margin-bottom: 1em }

ol.arabic {
  list-style: decimal }

ol.loweralpha {
  list-style: lower-alpha }

ol.upperalpha {
  list-style: upper-alpha }

ol.lowerroman {
  list-style: lower-roman }

ol.upperroman {
  list-style: upper-roman }

p.attribution {
  text-align: right ;
  margin-left: 50% }

p.caption {
  font-style: italic }

p.credits {
  font-style: italic ;
  font-size: smaller }

p.label {
  white-space: nowrap }

p.rubric {
  font-weight: bold ;
  font-size: larger ;
  color: maroon ;
  text-align: center }

p.sidebar-title {
  font-family: sans-serif ;
  font-weight: bold ;
  font-size: larger }

p.sidebar-subtitle {
  font-family: sans-serif ;
  font-weight: bold }

p.topic-title {
  font-weight: bold }

pre.address {
  margin-bottom: 0 ;
  margin-top: 0 ;
  font-family: serif ;
  font-size: 100% }

pre.line-block {
  font-family: serif ;
  font-size: 100% }

pre.literal-block, pre.doctest-block {
  margin-left: 2em ;
  margin-right: 2em ;
  background-color: #eeeeee }

span.classifier {
  font-family: sans-serif ;
  font-style: oblique }

span.classifier-delimiter {
  font-family: sans-serif ;
  font-weight: bold }

span.interpreted {
  font-family: sans-serif }

span.option {
  white-space: nowrap }

span.pre {
  white-space: pre }

span.problematic {
  color: red }

span.section-subtitle {
  /* font-size relative to parent (h1..h6 element) */
  font-size: 80% }

table.citation {
  border-left: solid thin gray }

table.docinfo {
  margin: 2em 4em }

table.docutils {
  margin-top: 0.5em ;
  margin-bottom: 0.5em }

table.footnote {
  border-left: solid thin black }

table.docutils td, table.docutils th,
table.docinfo td, table.docinfo th {
  padding-left: 0.5em ;
  padding-right: 0.5em ;
  vertical-align: top }

table.docutils th.field-name, table.docinfo th.docinfo-name {
  font-weight: bold ;
  text-align: left ;
  white-space: nowrap ;
  padding-left: 0 }

h1 tt.docutils, h2 tt.docutils, h3 tt.docutils,
h4 tt.docutils, h5 tt.docutils, h6 tt.docutils {
  font-size: 100% }

tt.docutils {
  background-color: #eeeeee }

ul.auto-toc {
  list-style-type: none }

</style>
</head>
<body>
<div class="document" id="yet-another-type-trait-decay">
<h1 class="title">Yet another type-trait: decay</h1>
<table class="docinfo" frame="void" rules="none">
<col class="docinfo-name" />
<col class="docinfo-content" />
<tbody valign="top">
<tr><th class="docinfo-name">Author:</th>
<td>Thorsten Ottosen</td></tr>
<tr><th class="docinfo-name">Contact:</th>
<td><a class="first last reference" href="mailto:tottosen&#64;dezide.com">tottosen&#64;dezide.com</a></td></tr>
<tr class="field"><th class="docinfo-name">organizations:</th><td class="field-body">Dezide Aps</td>
</tr>
<tr><th class="docinfo-name">Date:</th>
<td>2006-09-08</td></tr>
<tr class="field"><th class="docinfo-name">Number:</th><td class="field-body">WG21/N2069 J16/06-0139</td>
</tr>
<tr class="field"><th class="docinfo-name">Working Group:</th><td class="field-body">Library</td>
</tr>
</tbody>
</table>
<div class="contents topic">
<p class="topic-title first"><a id="table-of-contents" name="table-of-contents">Table of Contents</a></p>
<ul class="auto-toc simple">
<li><a class="reference" href="#introduction-and-motivation" id="id3" name="id3">1&nbsp;&nbsp;&nbsp;Introduction and Motivation</a></li>
<li><a class="reference" href="#wording" id="id4" name="id4">2&nbsp;&nbsp;&nbsp;Wording</a></li>
<li><a class="reference" href="#considerations-for-other-parts-of-the-library" id="id5" name="id5">3&nbsp;&nbsp;&nbsp;Considerations for other parts of the library</a></li>
<li><a class="reference" href="#acknowledgement" id="id6" name="id6">4&nbsp;&nbsp;&nbsp;Acknowledgement</a></li>
</ul>
</div>
<div class="section">
<h1><a class="toc-backref" href="#id3" id="introduction-and-motivation" name="introduction-and-motivation">1&nbsp;&nbsp;&nbsp;Introduction and Motivation</a></h1>
<p>The latest draft of the C++ standard (<a class="reference" href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2006/n2009.pdf">n2009</a>) includes
a new section on type traits. The type traits provide a consistent
and rich interface for compile-time type inspection and manipulation.</p>
<p>However, at least one very common trait is missing: <tt class="docutils literal"><span class="pre">decay</span></tt>. The purpose
of decay is best seen in connection <tt class="docutils literal"><span class="pre">std::make_pair()</span></tt> which is defined 
as follows:</p>
<pre class="literal-block">
template &lt;class T1, class T2&gt; 
inline pair&lt;T1,T2&gt; make_pair(T1 x, T2 y)
{ 
    return pair&lt;T1,T2&gt;(x, y); 
}
</pre>
<p>The arguments are passed by value primarily to ensure string literals
decay to <tt class="docutils literal"><span class="pre">const</span> <span class="pre">char*</span></tt> so as to make the following code work:</p>
<pre class="literal-block">
std::pair&lt;std::string,int&gt; p = std::make_pair(&quot;foo&quot;, 42);
</pre>
<p>If the arguments to <tt class="docutils literal"><span class="pre">make_pair()</span></tt> were passed by const reference, the above 
code would fail to compile because we suddenly create a temporary <tt class="docutils literal"><span class="pre">pair</span></tt> object
of the type <tt class="docutils literal"><span class="pre">std::pair&lt;const</span> <span class="pre">char[4],int&gt;</span></tt> (and this instantiation fails 
because arrays are not constructible with the <tt class="docutils literal"><span class="pre">T()</span></tt> syntax, 
nor are they copy-constructible).</p>
<p>The problem with the current definition of <tt class="docutils literal"><span class="pre">std::make_pair()</span></tt> is that it leads
to excessive copying of objects and hence great inefficiencies. With the advent of 
Rvalue References and perfect forwarding (see <a class="reference" href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2006/n2027.html">n2027</a>) we can easily 
remove all these
inefficiencies:</p>
<pre class="literal-block">
template &lt;class T1, class T2&gt; 
inline pair&lt;T1,T2&gt; make_pair(T1&amp;&amp; x, T2&amp;&amp; y)
{ 
    return pair&lt;T1, T2&gt;(std::forward&lt;T1&gt;(x), std::forward&lt;T2&gt;(y)); 
}
</pre>
<p>But alas, the above will still not compile and the reason is the same as before: we instantiate <tt class="docutils literal"><span class="pre">pair</span></tt> with an array type. However, with the proposed 
type-trait, the efficient version of <tt class="docutils literal"><span class="pre">std::make_pair()</span></tt> 
may be specified as follows:</p>
<pre class="literal-block">
template &lt;class T1, class T2&gt; 
inline pair&lt; typename decay&lt;T1&gt;::type, typename decay&lt;T2&gt;::type &gt; 
make_pair(T1&amp;&amp; x, T2&amp;&amp; y)
{ 
    return pair&lt; typename decay&lt;T1&gt;::type, 
                 typename decay&lt;T2&gt;::type &gt;(std::forward&lt;T1&gt;(x), 
                                            std::forward&lt;T2&gt;(y)); 
}
</pre>
<p>Simply put, <tt class="docutils literal"><span class="pre">decay&lt;T&gt;::type</span></tt> is the identity type-transformation except 
if <tt class="docutils literal"><span class="pre">T</span></tt> is an array type or a reference to
a function type. In those cases the <tt class="docutils literal"><span class="pre">decay&lt;T&gt;::type</span></tt> yields a pointer or 
a pointer to a function, respectively.</p>
<p>I believe the reason <a class="reference" href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1856.html">n1856</a> does not provide an efficient version 
of <tt class="docutils literal"><span class="pre">std::make_pair()</span></tt> is because of the lack of <tt class="docutils literal"><span class="pre">decay</span></tt>.</p>
<p>The type-trait has been part of boost since 1.33.0, and is used in libraries such as 
<a class="reference" href="http://www.boost.org/libs/assign/doc/index.html">Boost.Assign</a>.</p>
<p>The implementation may be found <a class="reference" href="http://boost.cvs.sourceforge.net/boost/boost/boost/type_traits/decay.hpp?view=markup">here</a>.</p>
</div>
<div class="section">
<h1><a class="toc-backref" href="#id4" id="wording" name="wording">2&nbsp;&nbsp;&nbsp;Wording</a></h1>
<p>Extend the synopsis of 20.4.2 to include the following:</p>
<pre class="literal-block">
// [20.4.8] other transformations:
template &lt;std::size_t Len, std::size_t Align&gt; struct aligned_storage;
template &lt;class T&gt; struct decay;
</pre>
<p>Add the following row to Table 46 (Other transformations):</p>
<table border="1" class="docutils">
<colgroup>
<col width="30%" />
<col width="19%" />
<col width="51%" />
</colgroup>
<thead valign="bottom">
<tr><th class="head"><strong>Template</strong></th>
<th class="head"><strong>Condition</strong></th>
<th class="head"><strong>Comments</strong></th>
</tr>
</thead>
<tbody valign="top">
<tr><td><tt class="docutils literal"><span class="pre">template</span> <span class="pre">&lt;class</span> <span class="pre">T&gt;</span> <span class="pre">struct</span> <span class="pre">decay;</span></tt></td>
<td>&nbsp;</td>
<td>If <tt class="docutils literal"><span class="pre">is_array&lt;T&gt;::value</span></tt> is <tt class="docutils literal"><span class="pre">true</span></tt>, the member typedef
<tt class="docutils literal"><span class="pre">type</span></tt> shall equal <tt class="docutils literal"><span class="pre">remove_extend&lt;T&gt;::type*</span></tt>.
If <tt class="docutils literal"><span class="pre">is_function&lt;T&gt;::value</span></tt> is <tt class="docutils literal"><span class="pre">true</span></tt>, the member typedef
<tt class="docutils literal"><span class="pre">type</span></tt> shall equal <tt class="docutils literal"><span class="pre">add_pointer&lt;T&gt;::type</span></tt>. Otherwise
the member typedef <tt class="docutils literal"><span class="pre">type</span></tt> equals <tt class="docutils literal"><span class="pre">T</span></tt>.</td>
</tr>
</tbody>
</table>
<p>Modify the synopsis of 20.2 to read:</p>
<pre class="literal-block">
template &lt;class T1, class T2&gt;
bool operator&lt;=(const pair&lt;T1,T2&gt;&amp;, const pair&lt;T1,T2&gt;&amp;);
template&lt;class T1, class T2&gt; 
pair&lt; typename decay&lt;T1&gt;::type, typename decay&lt;T2&gt;::type &gt; make_pair(T1&amp;&amp;, T2&amp;&amp;);
</pre>
<p>Modify the specification of 20.2.2 to read:</p>
<pre class="literal-block">
template&lt;class T1, class T2&gt; 
pair&lt; typename decay&lt;T1&gt;::type, typename decay&lt;T2&gt;::type &gt; make_pair(T1&amp;&amp; x, T2&amp;&amp; y);
</pre>
<p><em>Returns</em>: <tt class="docutils literal"><span class="pre">pair&lt;</span> <span class="pre">typename</span> <span class="pre">decay&lt;T1&gt;::type,</span> <span class="pre">typename</span> <span class="pre">decay&lt;T2&gt;::type</span> <span class="pre">&gt;(</span> <span class="pre">std::forward(x),</span> <span class="pre">std::forward(y)</span> <span class="pre">)</span></tt></p>
<p>and remove the footnote 226.</p>
</div>
<div class="section">
<h1><a class="toc-backref" href="#id5" id="considerations-for-other-parts-of-the-library" name="considerations-for-other-parts-of-the-library">3&nbsp;&nbsp;&nbsp;Considerations for other parts of the library</a></h1>
<p>The new tuple-library has a function called <tt class="docutils literal"><span class="pre">make_tuple()</span></tt> which is similar to
<tt class="docutils literal"><span class="pre">make_pair()</span></tt>. However, <tt class="docutils literal"><span class="pre">make_tuple()</span></tt> already takes its arguments by <tt class="docutils literal"><span class="pre">const</span></tt> reference.
In the near future I expect that all the TR1 components included the working draft needs to be made
move-aware. When that time comes, it is suggested that <tt class="docutils literal"><span class="pre">make_tuple()</span></tt> should make use of <tt class="docutils literal"><span class="pre">decay</span></tt> 
in the same way as <tt class="docutils literal"><span class="pre">make_pair()</span></tt> does above.</p>
</div>
<div class="section">
<h1><a class="toc-backref" href="#id6" id="acknowledgement" name="acknowledgement">4&nbsp;&nbsp;&nbsp;Acknowledgement</a></h1>
<p>Many thanks to John Maddock for his feedback.</p>
</div>
</div>
</body>
</html>
