<!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" >
<head>
<style type="text/css">
.comment { color: #999999; font-style: italic; }
.pre { color: #000099; }
.string { color: #009900; }
.char { color: #009900; }
.float { color: #996600; }
.int { color: #999900; }
.bool { color: #000000; font-weight: bold; }
.type { color: #FF6633; }
.flow { color: #FF0000; }
.keyword { color: #990000; }
.operator { color: #663300; font-weight: bold; }
.operator { color: #663300; font-weight: bold; }
pre.code {
    border: 2px solid #666;
    background-color: #F4F4F4;
    padding-left: 10px;
    padding-top: 0px;
}
code {
    border: 2px solid #d0d0d0;
    background-color: LightYellow;
    padding: 2px;
    padding-left: 10px;
    display:table;
    white-space:pre;
    margin:2px;
    margin-bottom:10px;
}
dt
{
    font-weight: bold;
}
    
.ins {
    background-color:#A0FFA0;
}

.del {
    background-color:#FFA0A0;
    text-decoration:line-through
}    
</style>    <title>Packaging Parameter Packs (Rev. 2)</title>
</head>
<body>
N3728
Revision of: N3416=12-0106<br />
    2013-09-03<br />
    Mike Spertus<br />
    <a href="mailto:mike_spertus@symantec.com"><tt>mike_spertus@symantec.com</tt></a><br/>

    <h1>
        Packaging 
        Parameter Packs (Rev. 2)</h1>
    <h2>
        Overview</h2>
    <p>
        The purpose of this paper is to propose mechanisms and rationale for named parameter packs and literal parameter packs.
        The main idea is to allow parameter packs to be created and named in non-template contexts by
        allowing parameter pack literals, which are just a template parameter list enclosed in angle brackets. In particular, 
        this proposal makes parameter packs suitable for use as typelists 
        and allows them to be defined and referenced from outside of template classes. While this is
        not ready for standardization, I want to give and idea of the main ideas and a number of use cases to get feedback from the Reflection working group
        in Chicago, so a complete proposal can be provided in Seattle.</p>
<h2>The fantasy</h2>
<p>We imagine (unconstrained for the moment by reality) a template class
<code>template &lt;typename... Ts&gt struct parameter_pack {};</code></p>
<p>We further imagine that a <em>template-parameter-list</em> (&sect;14p1)
surrounded by angle brackets could be used as a &ldquo;<tt>parameter_pack</tt> literal.&rdquo; 
<code>&lt;int, std::basic_ostream&lt;char&gt;&gt;  <span class="comment">// literal for parameter_pack&lt;int, ostream&gt;</span> </code></p>

<p>We could then create a named parameter
pack by <tt>typedef</tt>'ing it, like <code>typedef&lt;signed char, short int, int, long int, long long int&gt; signed_integral_types;</code></p>

<p>Of course, we would also want traditional declarations of parameter packs to also create named parameter packs.
<code>template&lt;typename... Ts&gt; struct S {
	static bool is_all_signed_integral_types() { return is_same&lt;Ts, signed_integral_types&gt;::value; } 
};
S&lt;double, float&gt;::is_all_signed_integral_types(); <span class="comment">// returns false</span>
S&lt;signed char, short int, int, long int, long long int&gt;::is_all_signed_integral_types(); <span class="comment">// returns true</span></code>
  </p>
<p>Of course, you would be able to instantiate parameter packs as usual:
<code>void f(signed_integral_types... sit) {
	(cout << sit << endl)...
}
f('c', 2, 5, 7L, 10LL);</code>It is worth pointing out that this behavior is difficult to
get currently if you have many functions that want <tt>signed_integral_types...</tt> (or other
patterns) in their
argument lists.</p>
<p>Of course, this would greatly simplify implementation of <tt>std::tuple</tt>:
<code>template&lt;typename... Ts&gt;
struct tuple {
  Ts... value;
};</code>
This would in no way obsolete the existing <tt>tuple</tt>, but would in fact allow
it to become much more powerful. For example, unpacking a tuple into an argument list
is a common need (See, the &ldquo;more perfect forwarding example&rdquo; in N3729.).
However, the implementation is extremely daunting, relying on a 40 line
<a href="http://stackoverflow.com/questions/687490/how-do-i-expand-a-tuple-into-variadic-template-functions-arguments">metafunction</a> 
due to DRayX, whose complexity is only hinted at by its length. Unpacking
tuples into argument lists would become trivial<code>void f(int, double, long);
tuple&lt;double, long&gt; tdl(3.4, 5L);
f(2, tdl.value...);</code></p>
<p>Likewise, explicit parameter packs would be a great base for metaprogramming
<code><span class="comment">// Inherits from true_type if typelist TL includes the type T</span>
template&lt;&lt;typename...&gt; TL, typename T&gt; struct includes;
<span class="comment">// Inherits from true_type if typelist TL includes all the types in TL2</span>
template&lt;&lt;typename...&gt; TL, &lt;typename...&gt; TL2&gt; struct contains;

<span class="comment">// The following asserts will not fire</span>
static_assert(includes&lt;&lt;double, int&gt;, int&gt;::value, "unexpected compile error");
static_assert(contains&lt;&lt;double, float, int&gt;, &lt;float, int&gt;&gt;, "unexpected compile error");</code></p>
<p>By having metafunctions return parameter packs, we can enable many use cases. For example,
if we want to generate parallel inheritance hierarchies as described in 
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2965.html">N2965</a>
and <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3492.pdf">N3492</a>,
we could write
<code><span class="comment">// B has the same base classes as A</span>
struct B : public direct_bases&lt;A&gt;::types... {};  <span class="comment">// See N2965 for direct_bases</span></code>
        Since template declarations can create parsing ambiguities (see Doug Gregor&#39;s 
            <a href="https://groups.google.com/forum/?fromgroups=#!topic/comp.std.c++/_-6X_xZlKlA">examples</a>), we adopt the now 
            familiar approach of explicitly identifying ambiguous members as parameter packs<code>template&lt;typename T&gt;
struct same_bases_as_T : public typename&lt;typename...&gt; direct_bases&lt;T&gt;::types... {};</code></p>

<p>Sometimes, metaprogramming would be vastly simplified. For example, in Alexandrescu's
seminal book <i>Modern C++ Design</i>, he devotes chapter 9 to factory templates. His abstract
factory is more or less equivalent to the following code:<code>template&lt;typename T&gt; struct Type2Type {};
 
template&lt;typename... Ts&gt; struct AbstractFactoryHelper;

template&lt;&gt; struct AbstractFactoryHelper&lt;&gt; {};

template&lt;typename T, typename... Ts&gt;
struct AbstractFactoryHelper&lt;T, Ts...&gt; : public AbstractFactoryHelper&lt;Ts...&gt; {
   virtual T *doCreate(Type2Type&lt;T&gt;) = 0;
};

template&lt;typename... Ts&gt;
struct AbstractFactory : public AbstractFactoryHelper&lt;Ts...&gt; {
  template&lt;typename T&gt;
  T *create() {
    return doCreate(Type2Type&lt;T&gt;());
  }
}</code></p>
<p>In our &ldquo;fantasy,&rdquo; we would want the implementation to simply become
(also leveraging the <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3405.html#virtual">Virtual template methods proposal</a>)
<code>template&lt;typename... Ts&gt;
struct AbstractFactory {
   template&lt;typename T&gt; doCreate();
   template&lt;&gt; virtual Ts *create() = 0;...
}</code></p>

<h2>Reality</h2>
<p>It's time to stop fantasizing and think about whether the fantasy can be made real. I think
it can and will be demonstrating partial compiler support in Chicago. There is also need
for more precise wording. For example, we need something like <tt>-&gt;...</tt> for the same
sort of reasons we need <tt>-&gt;template</tt>.</p>
<p>My hope is to present this to the reflection working group for input as to whether this
is a direction we would like to pursue, in which case, I will come to Seattle with a fully
worded and implemented proposal.</p>
<h2>Why not just use <tt>tuple</tt>?</h2>
    <p>The first question to ask of course is whether typelists belong in library or 
        evolution. Many people have taken a library-based approach to typelists</p>
    <ul>
        <li>In <a href="http://www.jot.fm/issues/issue_2008_02/article2/">Variadic Templates for C++0x</a>, 
        it is suggested that <tt>tuple</tt> be used as a typelist 
        in lieu of language support. </li>
        <li>An influential <a href="http://erdani.com/index.php/books/modern-c-design/">book</a> 
        has been written about using 
            typelists provided by the Loki library [<a href="http://loki-lib.sourceforge.net/">6</a>].</li>
        <li>It is also common to create a simple typelist class 
        like <code>template&lt;typename... T&gt; struct typelist {};</code></li>
        <li>Boost.MPL provides a panoply of type containers, generalizing typelists</li>
        </ul>
        This plethora of libraries leveraging typelists 
    testifies to their value. 
    However, the primitive templates the typelists are based on form a weak 
    foundation, limiting the applicability of those libraries. It is not our aim to replace
    these libraries, merely to give them a robust, scalable, and usable parameter pack
    primitive to build off. We illustrate this by comparing the &ldquo;<tt>tuple</tt> as typelist&rdquo; 
    suggestion to packaged parameter packs:
    <dl>
    <dt>Performance</dt>
    <dd>Compilation speed is often gating in metaprogramming. In implementating the <tt>bases</tt> trait proposed in N3729 
            as a g++4.7 extension, I compared the performance of returning a <tt>tuple</tt> 
            type giving all the base classes of a class with returning a simple typelist 
            class containing no members and no recursive expansion. The simple typelist class was 60 
            times faster to compile. A built-in parameter list would presumably be even faster than 
            that. Given that the recursive member generation in <tt>tuple</tt> provides no benefit for 
            typelists, <tt>tuple</tt>-based typelists should probably be avoided for performance reasons 
            alone.</dd>
<dt>Interoperability</dt>
<dd>If <tt>tuple</tt>s are used as typelists, it is difficult to convert between <tt>tuple</tt>s 
    and parameter packs, meaning sometimes you will have code that expects a <tt>tuple</tt> 
    and other times code expecting a parameter pack. For example, passing a <tt>tuple</tt>&#39;s arguments to another template&#39;s argument 
        list is awkward.
 <code><span class="comment">// Passing tuple's parameters to another template</span>
template&lt;template&lt;typename...&gt; class F, typename T&gt; struct unwrap_into;

template&lt;template&lt;typename...&gt; class F, typename... Ts&gt;
struct unwrap_into&lt;F, tuple&lt;Ts...&gt;&gt; {
  typedef F&lt;Ts...&gt; type;
};

typedef tuple&lt;double, string&gt; tds;
unwrap_into&lt;map, tds&gt;::type map_double_to_string;
</code>
By contrast, this is almost trivial when using parameter packs.
<code>typedef&lt;double, string&gt; tds;
map&lt;tds...&gt; map_double_to_string;</code>
<p>What makes it worse is that how to expand the tuple&#39;s parameters can vary case by case. For example, to inherit from all of the types in a <tt>tuple</tt>, you might do something like</p>
<code>template&lt;typename T&gt; struct inherit;
template&lt;typename... Ts&gt;
struct inherit&lt;tuple&lt;Ts...&gt;&gt; : public Ts... {};

typedef tuple&lt;interface1, interface2&gt; interfaces;
struct myType : public inherit&lt;interfaces&gt; {};</code>
With parameter pack-based typelists, it's no contest
<code>typedef&lt;interface1, interface2&gt; interfaces;
struct myType : public interfaces... {};
</code></dd>
<dt>Non-type parameters</dt>
<dd>A <tt>tuple</tt> cannot have non-type template parameters, so it cannot encapsulate 
    general lists of template parameters (OK. Maybe a <tt>constexpr tuple</tt> could be used. 
    But even that wouldn&#39;t work if some parameters are types and others are non-type 
    parameters). Consider this example, which returns the 
    methods of a particular class. Note that a putative reflection trait for enumerating 
    methods would also have the same issue.
<code>struct A {
  void f();
  int g();
};
<span class="comment">// Package the methods of A</span>
typedef&lt;&amp;A::f, &amp;A::g&gt; A_methods;
</code></dd>
    <dt>Template expansion limits</dt>
    <dd>Tuples are subject to severe template expansion limits. Under 
            Visual Studio, a template can have at most 64 template parameters. This is 
            insufficient for many important use cases for typelists. For example, 
            compile-time reflection proposals often propose returning a typelist of 
            metaobjects for all of the members of a class or all of the symbols in a 
            namespace. This could far overrun the limits for template parameters (Just consider 
            enumerating the symbols in namespace <tt>std</tt>).&nbsp; By contrast, parameter 
        packs are a kind of degenerate template type, which cannot have members, cannot 
        be specialized, etc. My implementation actually generates a class with members
        rather than a variadic template class to avoid these limits.</dd>

</dl>

</body>
</html>
