This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
[c++0x] parameter packs in class templates
- From: Jan van Dijk <jan at epgmod dot phys dot tue dot nl>
- To: gcc at gcc dot gnu dot org
- Date: Wed, 22 Aug 2007 12:28:49 +0200
- Subject: [c++0x] parameter packs in class templates
- Reply-to: jan at epgmod dot phys dot tue dot nl
Good afternoon,
Today I started to play around with g++' c++0x mode. I tried to compile the
following toy program:
template<class T, class... Pack>
struct pack_size
{
enum { value = 1 + pack_size<Pack...>::value };
};
template <class T>
struct pack_size<T>
{
enum { value = 1 };
};
struct A{};
void foo()
{
static_assert(pack_size<A,A,A>::value==3,"Pack size error");
}
With today's trunk this does not compile:
$ g++ -c -std=c++0x t.cpp
t.cpp:4: error: cannot expand âPack ...â into a fixed-length argument list
I was surprised by this message: since the second argument of the primary
pack_size template is a parameter pack, the argument list is (at least
conceptually) not of fixed length. After removing the test that generates
this diagnostic from gcc/cp/pt.c (see patch at the bottom of this message),
the code compiles fine.
* assuming the code is valid, my 'fix' is probably not correct (I now nothing
about C++ internals). The intention of this patch is that, if we pass (only)
a parameter pack to a context that expects (non-pack) template arguments,
_followed by_ a parameter pack, the first parameters should be stripped off
the pack. What remains of the pack is used as the last (pack) parameter. This
is consistent with my understanding of how variadic _function_ templates
work.
* I read n2152.pdf, only to find out that that document refers (almost)
exclusively to variadic _function_ templates. I did not find anything that
discusses my use-case.
* If the standard is not explicit about the validity of this code: If a pack
expansion is equivalent to the sequence formed by its members, I guess that
my code should be valid. In that case the problematic
code 'pack_size<Pack...>' on line 4 is equivalent to the code
pack_size<A,A,A> (line 17) that is fine (?).
Thank you for considering this issue.
With kind regards,
Jan van Dijk.
Index: pt.c
===================================================================
--- pt.c (revision 127686)
+++ pt.c (working copy)
@@ -5034,7 +5034,7 @@
else if (arg_idx < nargs)
{
arg = TREE_VEC_ELT (inner_args, arg_idx);
-
+#if 0
if (arg && PACK_EXPANSION_P (arg))
{
/* If ARG is a pack expansion, but PARM is not a
@@ -5048,6 +5048,7 @@
error ("cannot expand %<%T%> into a fixed-length "
"argument list", arg);
}
+#endif
}
else if (require_all_args)
/* There must be a default arg in this case. */