Bug 47226 - [C++0x] GCC doesn't expand template parameter pack that appears in a lambda-expression
Summary: [C++0x] GCC doesn't expand template parameter pack that appears in a lambda-e...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.6.0
: P3 normal
Target Milestone: 8.0
Assignee: Not yet assigned to anyone
URL:
Keywords:
: 64488 83793 (view as bug list)
Depends on:
Blocks: 54367
  Show dependency treegraph
 
Reported: 2011-01-08 20:58 UTC by Johannes Schaub
Modified: 2018-04-09 18:59 UTC (History)
16 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2013-05-21 00:00:00


Attachments
Testcase for bug 47226 (205 bytes, text/plain)
2013-12-30 23:53 UTC, Dennis Brentjes
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Johannes Schaub 2011-01-08 20:58:54 UTC
GCC doesn't like this:

  void slurp(...) { } 
  template<int ...N> 
  void print() { 
    slurp([]() -> int { 
      (void) N; // or something fancy...
      return 0; 
    }() ...); 
  }

  void f() { print<1, 2>(); }

Error:

  error: parameter packs not expanded with '...':

I think the draft (n3225) says this should expand "N" and result in: 

  slurp(
    []() -> int { 
      (void) 1; // or something fancy...
      return 0; 
    }(),
    []() -> int { 
      (void) 2; // or something fancy...
      return 0; 
    }());
Comment 1 Johannes Schaub 2012-01-08 11:41:18 UTC
I asked the committee at that time, and they reinforced that this is intended to work as specified in the C++11 spec.
Comment 2 Daniel Krügler 2012-06-26 20:25:16 UTC
The problem still exists in gcc 4.8.0 20120610 (experimental) compiled with 
-Wall -pedantic -std=c++11. Here a variation of Johannes example based on a similar Clang bug report from Doug Gregor:

//----
template<class T>
void print(const T&) {}

template<class... T>
void accept_all(T&&...){}

template<class... T>
void print_all(const T&... t)
{
  accept_all([&]()->int { print(t); return 0; }...);  // Line 10
}

int main()
{
  print_all(1, true, 'a');
}
//----

"10|error: parameter packs not expanded with '...':|
10|note:         't'|
|In function 'void print_all(const T& ...)':|
10|error: expansion pattern '#'lambda_expr' not supported by dump_expr#<expression error>' contains no argument packs"
Comment 3 gnzlbg 2012-11-18 17:38:49 UTC
Is this a duplicate of Bug 41933 ?
Comment 4 Johannes Schaub 2012-11-18 21:29:15 UTC
(In reply to comment #3)
> Is this a duplicate of Bug 41933 ?

This looks like a different one. I am not trying to capture a list of variables that result of expansion of a function parameter pack, but I'm just trying to use an element (a type or in this case, a non-type template parameter) of a pack expansion within a lambda. 

For a real life example, consider http://stackoverflow.com/a/13444602/34509
Comment 5 Dennis Brentjes 2013-12-30 23:53:14 UTC
Created attachment 31544 [details]
Testcase for bug 47226

I encountered this bug last week with gcc 4.8.1. I attached a minimal test case for this bug and was wondering if there is any progress on implementing this feature. As I understand parameter packs in combination with lambdas weren't implemented until bug 41933 was fixed in September this year. So I'm hoping somebody is working on this particular bug as well.
Comment 6 Michał Dominiak 2015-10-06 18:02:13 UTC
This still exists in GCC 6.0.0 20150902 (also I've heard MSVC manages to work with this. Come on, guys, don't be worse than MSVC *when it comes to templates*. Clang of course also understands what's going on).
Comment 7 Tatsuyuki Ishi 2016-04-29 05:41:55 UTC
I'm suffering from this bug too. It currently break my CI since I can't use clang too due to ABI changes.

This is 3 years-old: I hope someone will take a look on it.
Comment 8 Akim Demaille 2016-05-18 13:05:57 UTC
I'm hit too.
Comment 9 Vittorio Romeo 2016-11-23 08:55:18 UTC
Got hit as well, in g++ 7.0 trunk:
http://stackoverflow.com/questions/40752568
Comment 10 Matthias Kretz 2017-07-06 12:25:48 UTC
I have the following in my code now:

    // this could be much simpler:
    //
    // return {V([&](auto i) { return x[i + Indexes * V::size()]; })...};                                                               
    //
    // Sadly GCC has a bug: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47226. The                                                     
    // following works around it by placing the pack outside of the code block of the                                                 
    // lambda:                                                                                                                          
    return {[](size_t j, const datapar<T, A> &y) {                                                                                      
        return V([&](auto i) { return y[i + j * V::size()]; });                                                                         
    }(Indexes, x)...};
Comment 11 Akim Demaille 2017-07-06 12:30:17 UTC
The project I work on has this:

    auto const f = std::bind(&Rpc::operator (),
                             &rpc, std::ref(args)...);

instead of a simple lambda.
Comment 12 Akim Demaille 2017-07-06 12:30:51 UTC
The project I work on has this:

    auto const f = std::bind(&Rpc::operator (),
                             &rpc, std::ref(args)...);

instead of a simple lambda.
Comment 13 paolo@gcc.gnu.org 2017-09-13 09:47:42 UTC
Author: paolo
Date: Wed Sep 13 09:47:11 2017
New Revision: 252064

URL: https://gcc.gnu.org/viewcvs?rev=252064&root=gcc&view=rev
Log:
2017-09-13  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/47226
	* g++.dg/cpp0x/lambda/lambda-variadic4.C: New.
	* g++.dg/cpp0x/lambda/lambda-variadic5.C: Likewise.

Added:
    trunk/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-variadic4.C
    trunk/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-variadic5.C
Modified:
    trunk/gcc/testsuite/ChangeLog
Comment 14 Paolo Carlini 2017-09-13 09:49:31 UTC
Fixed by Jason's https://gcc.gnu.org/ml/gcc-patches/2017-08/msg01678.html. I added a couple of testcases and I'm closing the bug.
Comment 15 Paolo Carlini 2017-09-13 18:30:31 UTC
*** Bug 64488 has been marked as a duplicate of this bug. ***
Comment 16 Martin Sebor 2018-01-13 17:50:29 UTC
*** Bug 83793 has been marked as a duplicate of this bug. ***
Comment 17 Vittorio Romeo 2018-04-08 21:59:09 UTC
Was the patch merged in trunk?
The following still fails to compile on 20180407

template <int... Is>
int foo()
{
    ([i = Is]{}(), ...); 
    return 0;
}
Comment 18 Jonathan Wakely 2018-04-09 17:48:29 UTC
(In reply to Vittorio Romeo from comment #17)
> Was the patch merged in trunk?

It was committed to trunk: r251433

> The following still fails to compile on 20180407

Could you create a new bug for that please?
Comment 19 Vittorio Romeo 2018-04-09 18:59:53 UTC
(In reply to Jonathan Wakely from comment #18)
> (In reply to Vittorio Romeo from comment #17)
> > Was the patch merged in trunk?
> 
> It was committed to trunk: r251433
> 
> > The following still fails to compile on 20180407
> 
> Could you create a new bug for that please?

Created
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85305