Bug 64488 - [c++11] Expand initializer list with lambdas in variadic template. Reject valid code.
Summary: [c++11] Expand initializer list with lambdas in variadic template. Reject val...
Status: RESOLVED DUPLICATE of bug 47226
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 5.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: c++-lambda, rejects-valid
Depends on:
Blocks: lambdas
  Show dependency treegraph
 
Reported: 2015-01-04 16:00 UTC by reagentoo
Modified: 2022-03-11 00:32 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2015-01-04 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description reagentoo 2015-01-04 16:00:17 UTC
The following valid code snippet (compiled with "-std=c++11") rejected in GCC 5.0.0 (20150103) but compiles with Clang normal:
=======================================================
#include <iostream>

template <int _i>
struct Lmb
{
    static void fff() { std::cout << _i << std::endl; }
};

template <int... _is>
struct Expand
{
    Expand() { }

    static constexpr uint m_size = sizeof...(_is);

    static void (*const m_arr[m_size])();
};
template <int... _is>
void (*const Expand<_is...>::m_arr[m_size])() = {
        [] () { std::cout << _is << std::endl; } ...
        //Lmb<_is>::fff...
};


int main()
{
    Expand<12,34,56> e;
    e.m_arr[0]();
    e.m_arr[1]();
    e.m_arr[2]();
    
    return 24;
}
=======================================================
GCC 5.0.0 (20150103) output:
-------------------------------------------------------
prog.cc: In lambda function:
prog.cc:20:46: error: parameter packs not expanded with '...':
        [] () { std::cout << _is << std::endl; } ...
                                             ^
prog.cc:20:46: note:         '_is'
prog.cc: At global scope:
prog.cc:20:50: error: expansion pattern '<lambda>' contains no argument packs
        [] () { std::cout << _is << std::endl; } ...
                                                 ^
Comment 1 Jonathan Wakely 2015-01-04 16:10:45 UTC
Reduced:

template <int... _is>
struct Expand
{
    static void (*const m_arr[sizeof...(_is)])();
};

template <int... _is>
void (*const Expand<_is...>::m_arr[])() = {
        [] () { (void)_is; } ...
};

int main()
{
    Expand<12,34,56> e;
    e.m_arr[0]();
    e.m_arr[1]();
    e.m_arr[2]();
}
Comment 2 Jonathan Wakely 2015-01-04 16:12:04 UTC
probably a dup of PR 47226
Comment 3 Vittorio Romeo 2017-02-20 10:48:53 UTC
Further simplification:

    template <int... Is>
    void foo() 
    {
        using arr = int(*[])();
        (void) arr{[]{ return Is; }...};
    }

    int main() { foo<1,2,3>(); }



* clang++ 3.3 (up to 5.0) happily compiles the code with -std=c++11.

* g++ 4.7 (up to 7.0) fails to compile with -std=c++11 (or c++14/c++1z)
Comment 4 Paolo Carlini 2017-09-13 18:30:31 UTC
Fixed.

*** This bug has been marked as a duplicate of bug 47226 ***