C ++: extension of parameter package inside lambda fails

I am trying to create a way to directly expand multiple parameter packages. I created a function template<size_t X,typename F> auto sequenceFunc(F&& f) that calls the given function f with extended integer_sequence .

This works well for small functions such as:

 template<typename T, size_t A,size_t B> vec<B,T> col(const mat<A,B,T>& a,const size_t& i){ return sequenceFunc<A>([&](auto... J) -> vec<B,T>{ return { a[J][i]... }; //expands to a[0][i], a[1][i], ... a[A-1][i] }); } 

Unfortunately, I cannot extend several parameter packages, even if I follow the rule that only one parameter package can be inside an expression ... This is my attempt to use this function for matrix multiplication:

 template<typename S,typename T, size_t A,size_t B,size_t C> mat<C,B,S> mul(const mat<A,B,S>& a,const mat<C,A,T>& b){ return sequenceFunc<B>([&](auto... I)->mat<C,B,S>{ //for all B rows in a... return { sequenceFunc<C>([&](auto... J)->vec<C,S>{ // ... look at all C columns in b and calculate dot product. auto i = I; //putting "I" outside the expansion of "J" return { dot(row(a,i),col(b,J))... //expands J }; })... //expands I }; }); } 

This is mistake:

 error: parameter packs not expanded with '...': auto i = I; ^ 

I do not understand why the extension is necessary, because beyond the expression there is still ... I am using GCC 5.1.0.

The vec and mat info is just using -declarations for std::array and nested std::array<std::array<A,T>,B>

+5
source share
2 answers

This is gcc error 47226 . It is still open, and the sample code still doesn't work on gcc 5.2.0, while it compiles just fine on clang 3.6. Your code looks right to me.

+4
source

I ran into the same problem. I did not find a better deception and did not want to open a new question, but still I want to share my conclusions. In the commentary on a similar question, I found a workaround that puts the parameters in a tuple and then decompresses it inside the lambda (sorry, you wonโ€™t find the link anymore). However, this solution requires C ++ 17 ( std::apply and more).

In my case, there was something like this:

 struct Foo{ template <typename T,typename ...ARGS> void foo(T t,ARGS...args){ auto x = [&](){ t(args...);} } }; 

which does not work with gcc 4.8.5. To my surprise, just explicitly exposing the lambda as a functor works like a charm:

 template <typename T,typename ...ARGS> struct FooFunct{ void operator()(T t,ARGS...args){ t(args...); } }; struct Foo{ template <typename T,typename ...ARGS> void foo(T t,ARGS...args){ auto x = FooFunct<T,ARGS...>(); } }; 

It seems a little strange to me that gcc swallows this, and not the first. Afaik lambdas is just syntactic sugar for anonymous function functors. Probably my knowledge in compilers is too small to understand what the problem is in fixing this error.

0
source

All Articles