Bug 48424

Summary: C++0x parameter packs expansion problem
Product: gcc Reporter: Luca Mattiello <aiedail92>
Component: c++Assignee: Jason Merrill <jason>
Status: RESOLVED FIXED    
Severity: normal CC: jason
Priority: P3 Keywords: rejects-valid
Version: 4.7.0   
Target Milestone: 4.6.1   
Host: Target:
Build: Known to work:
Known to fail: Last reconfirmed: 2011-04-04 18:16:41

Description Luca Mattiello 2011-04-03 13:42:40 UTC
The following testcase, which should be valid (at least I think so), fails to compile:


#include <tuple>
#include <functional>

template<typename... T>
struct test
{
    std::tuple<int, T..., long> t;          // OK
    void(*fptr)(int, T..., long);           // Error (1)
    std::function<void(int, T..., long)> f; // Error (2)
};


Since in (1) and (2) T... is not a parameter pack declaration, but a parameter pack expansion, shouldn't the code be valid? And if it's really not valid, is there a good explanation for this?


luca@laptop-luca:~$ g++ --version
g++ (GCC) 4.7.0 20110330 (experimental)

luca@laptop-luca:~$ g++ -std=c++0x testcase.cc 
testcase.cc:8:32: error: parameter packs must be at the end of the parameter list
testcase.cc:9:39: error: parameter packs must be at the end of the parameter list
Comment 1 Jonathan Wakely 2011-04-03 15:13:50 UTC
It certainly looks reasonable. Jason, should this be accepted?
Comment 2 Jason Merrill 2011-04-04 18:16:41 UTC
Yes, that's an obsolete restriction that has been removed from the draft; 8.3.5/13 used to say "A function parameter pack, if present, shall occur at the end of the parameter-declaration-list." but it doesn't any more.
Comment 3 Jonathan Wakely 2011-04-18 21:23:46 UTC
Jason, when this bug is fixed will this be allowed too?

template<typename... Args1>
struct S
{
  template<typename... Args2>
    void f(Args1... args1, Args2&&... args2)
    {
    }
};

S<int, int> s;

Currently this gives:

var.cc:5:47: error: parameter packs must be at the end of the parameter list

But it seems like it should be ok since sizeof...(Args1) is fixed when calling S::f and so shouldn't interfere with deducing Args2

(I wanted to do something of this form to make std::mem_fn support varargs member functions such as R (T::*)(int, ...) where Args1 would be [int] and Args2 would be the additional arguments passed to _Mem_fn::operator())
Comment 4 Jason Merrill 2011-04-18 22:45:55 UTC
Yes, that looks OK too.
Comment 5 Jason Merrill 2011-05-26 13:22:54 UTC
Author: jason
Date: Thu May 26 13:22:51 2011
New Revision: 174285

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=174285
Log:
	PR c++/48424
	* decl.c (grokparms): Function parameter packs don't need to
	go at the end.
	* pt.c (type_unification_real): But they aren't deduced otherwise.

Added:
    trunk/gcc/testsuite/g++.dg/cpp0x/variadic111.C
Modified:
    trunk/gcc/cp/ChangeLog
    trunk/gcc/cp/decl.c
    trunk/gcc/cp/pt.c
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/testsuite/g++.dg/cpp0x/variadic41.C
Comment 6 Jason Merrill 2011-05-26 13:44:06 UTC
Fixed for 4.6.1.
Comment 7 Jason Merrill 2011-05-26 13:44:26 UTC
Author: jason
Date: Thu May 26 13:44:20 2011
New Revision: 174287

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=174287
Log:
	PR c++/48424
	* decl.c (grokparms): Function parameter packs don't need to
	go at the end.
	* pt.c (type_unification_real): But they aren't deduced otherwise.

Added:
    branches/gcc-4_6-branch/gcc/testsuite/g++.dg/cpp0x/variadic111.C
Modified:
    branches/gcc-4_6-branch/gcc/cp/ChangeLog
    branches/gcc-4_6-branch/gcc/cp/decl.c
    branches/gcc-4_6-branch/gcc/cp/pt.c
    branches/gcc-4_6-branch/gcc/testsuite/ChangeLog
    branches/gcc-4_6-branch/gcc/testsuite/g++.dg/cpp0x/variadic41.C