Bug 40155 - [c++0x] variadic template pack problem
Summary: [c++0x] variadic template pack problem
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.5.0
: P3 normal
Target Milestone: 4.5.0
Assignee: Dodji Seketeli
URL:
Keywords: rejects-valid
Depends on:
Blocks:
 
Reported: 2009-05-15 02:55 UTC by Wolfgang Bangerth
Modified: 2010-02-07 04:02 UTC (History)
5 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2010-01-04 23:12:53


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Wolfgang Bangerth 2009-05-15 02:55:37 UTC
I'm fairly sure this should compile but it doesn't:
---------------------
template <typename T> struct identity
{  typedef T type;  };

template <typename RT, typename... A>
int forward_call(RT (*) (A...), typename identity<A>::type...);

int g (double);

int i = forward_call(&g, 0);
-------------------------------------

The problem is the expansion
  typename identity<A>::type...
which should wrap identity<An>::type around each element An of the
template pack A. I'm not entirely familiar with all the rules for
template packs yet, but I think that this should work, taking
the examples in
  http://www.jot.fm/issues/issue_2008_02/article2/
into account.

Best
 W.
Comment 1 Wolfgang Bangerth 2009-05-15 02:56:19 UTC
Oh, should've said:

g/x> /home/bangerth/bin/x86/gcc-mainline/bin/c++ -std=c++0x -c x.cc
x.cc:9: error: invalid conversion from 'int (*)(double)' to 'int (*)()'
x.cc:5: error: too many arguments to function 'int forward_call(RT (*)(A ...), typename identity<A>::type ...) [with RT = int, A = , typename identity<A>::type = A]'
x.cc:9: error: at this point in file
Comment 2 Dodji Seketeli 2010-01-05 11:43:50 UTC
FWIW, I think this code is valid.

The A template parameter in "typename identity<A>::type..." is in a non-deduced context, so it's argument should not be deduced from there. The argument of A should be re-used from the deduction done using "RT (*) (A...)".

And I think that's where the problem is. Once the compiler figured the second argument of forward_call is a non-deduced context, it fails to re-use the argument of A that was deduced in the context of the first argument of forward_call.

I believe this should be flagged P1, even if it doesn't seem to be a regression.
Comment 3 Wolfgang Bangerth 2010-01-05 13:20:20 UTC
(In reply to comment #2)
> I believe this should be flagged P1, even if it doesn't seem to be a
> regression.

I'm obviously not impartial, but this is the sort of code that template
packs are supposed to support, and forwarding calls is one of its main
objectives. So I would definitely support getting this to work in 4.5...

W.
Comment 4 Dodji Seketeli 2010-01-05 13:31:52 UTC
Patch submitted to http://gcc.gnu.org/ml/gcc-patches/2010-01/msg00205.html
Comment 5 Dodji Seketeli 2010-01-07 19:22:20 UTC
Subject: Bug 40155

Author: dodji
Date: Thu Jan  7 19:21:46 2010
New Revision: 155705

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=155705
Log:
Fix PR c++/40155

gcc/cp/ChangeLog:
	c++/40155
	* pt.c (unify_pack_expansion): In non-deduced contexts, re-use template
	arguments that were previously deduced.

gcc/testsuite/ChangeLog:
	c++/40155
	* g++.dg/cpp0x/variadic-unify-2.C: New test.

Added:
    trunk/gcc/testsuite/g++.dg/cpp0x/variadic-unify-2.C
Modified:
    trunk/gcc/cp/ChangeLog
    trunk/gcc/cp/pt.c
    trunk/gcc/testsuite/ChangeLog

Comment 6 Dodji Seketeli 2010-01-07 19:47:45 UTC
Fixed in 4.5