Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.std.c++ > #579

Variadic template parameter pack matching non-pack parameters

From Sylvester Hesp <usenet@oisyn.nl>
Newsgroups comp.std.c++
Subject Variadic template parameter pack matching non-pack parameters
Date 2013-01-12 11:23 -0800
Organization A noiseless patient Spider
Message-ID <kcd5vj$n3k$1@dont-email.me> (permalink)

Show all headers | View raw


[To the moderators: this is my second attempt, the first one posted
using Google Groups went into the void. Also, a mail to
std-c++-request@cs.rpi.edu was being rejected because "User address is
not valid"]

I was playing around with the November '12 CTP preview of the VC++11
compiler, which includes an implementation of variadic templates, and
something interesting caught my eye.

Consider the following program:

===================
template<class T, class U>
struct Foo { };

template<class... Args>
void Bar(Foo<Args...> f)
{
}

template<class... Args>
void Baz()
{
	Foo<Args...> f;
}

int main()
{
	Foo<int, float> f;
	Bar(f);					// #1
	Bar<int, float>(f);		// #2
	Baz<int, float>(f);		// #3
}
===================

This fails to compile using both VC++11 and GCC 4.6.3 (unfortunately I
was not able to test a more recent version). VC++ in particular reports
these errors:

===================
test1.cpp(5): error C2976: 'Foo' : too few template arguments
          test1.cpp(2) : see declaration of 'Foo'
test1.cpp(18): error C2664: 'void Bar<>(Foo)' : cannot convert
parameter 1 from 'Foo<int,float>' to 'Foo'
          No user-defined-conversion operator available that can
perform this conversion, or the operator cannot be called
test1.cpp(20): error C2780: 'void Baz(void)' : expects 0 arguments - 1
provided
          test1.cpp(10) : see declaration of 'Baz'
===================

I was confused. The first error just seems plain silly - why would it
complain *at definition time of Bar* that Foo has too few template
parameters, if it doesn't yet know the Args parameter pack will be
expanded at instantiation time? Especially given the fact that at #2 no
errors are reported where the template parameters are explicitely
specified, and that Foo is appropriately instantiated in Baz() at #3.
Of course, a specific instantiation could use a different number of
parameters allowed for Foo, but this would then be a clear case of
SFINAE (Bar() I mean, Baz() would be ill-formed).

Also, it fails to deduce the template parameters in #1. Albeit somewhat
less clear that the compiler should be able to deduce a parameter pack
using a list of non-pack parameters in the argument, I recon this is
analogous to matching function parameters like 'R(Args...)', so I would
think that it should also be able to deduce the pack in this particular
case.

My first reasoning was that I was simply hitting a compiler bug in
VC++, but then I found out that GCC reported similar errors. Then I
started to read up on the standard, especially sections 14.5.3
[temp.variadic] and 14.8.2 [temp.deduct] and I found no clear rules why
above program would be ill-formed. However, I did find the following
paragraphs that, in my opinion, at the very least /hint/ that the
program is correct:

14.5.3/4 Decribes that a pack expansion could occur in a
/template-argument-list/, which I believe is the case in the
declaration of Bar.

It is not being mentioned in the non-deduced contexts in 14.8.2.5/5

14.8.2.5/8 States that a deduction can be made in the case of
template-name<T>

And furthermore, 14.8.2.5/9 pretty much states that "If P has a form
that contains <T> or <i>, [...] If Pi is a pack expansion, then the
pattern of Pi is compared with each remaining argument in the template
argument list of A. Each comparison deduces template arguments for
subsequent positions in the template parameter packs expanded by Pi"

Am I right in asserting that, based on above paragraphs, the program is
in fact well-formed C++11, and it just so happens that both VC++ as GCC
have a bug in this regard?


Regards,

Sylvester Hesp



-- 
[ comp.std.c++ is moderated.  To submit articles, try posting with your ]
[ newsreader.  If that fails, use mailto:std-cpp-submit@vandevoorde.com ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]

Back to comp.std.c++ | Previous | NextNext in thread | Find similar


Thread

Variadic template parameter pack matching non-pack parameters Sylvester Hesp <usenet@oisyn.nl> - 2013-01-12 11:23 -0800
  Re: Variadic template parameter pack matching non-pack parameters Daniel Krügler <daniel.kruegler@googlemail.com> - 2013-01-13 14:33 -0600
  Re: Variadic template parameter pack matching non-pack parameters "terminator(jam)" <farid.mehrabi@googlemail.com> - 2013-04-02 15:56 -0700
    Re: Variadic template parameter pack matching non-pack parameters Daniel Krügler <daniel.kruegler@googlemail.com> - 2013-04-04 19:05 -0600

csiph-web