Reputation: 1272
I'm trying to create a way to directly expand multiple parameter packs. I have created a function template<size_t X,typename F> auto sequenceFunc(F&& f)
, that calls a given function f
with a expanded integer_sequence
.
This works well for small functions like this:
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 can't expand multiple parameter packs, even if I follow the rule, that only one parameter pack can be inside a ...
-expression.
This is my attempt at using 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 the error:
error: parameter packs not expanded with '...':
auto i = I;
^
I don't really understand why an expansion is necessary, because there is another ...
outside the expression. I use GCC 5.1.0.
Information vec
and mat
are only using
-declarations for std::array
and a nested std::array<std::array<A,T>,B>
Upvotes: 5
Views: 637
Reputation: 122820
I just encountered the same problem. Didnt find a better dupe and didnt want to open a new question, but still want to share my findings. In a comment to a similar question I found a workaround that puts the parameters in a tuple and then unpacks it inside the lambda (sorry dont find the link anymore). However, that solution requires C++17 (std::apply
and more).
My case was something like this:
struct Foo{
template <typename T,typename ...ARGS>
void foo(T t,ARGS...args){
auto x = [&](){ t(args...);}
}
};
which is not working with gcc 4.8.5. To my surprise, simply explicitly writing out the lambda as 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...>();
}
};
I find it a bit strange, that gcc swallows this, while not the first one. Afaik lambdas are just syntactic sugar for anonymous functors on function scope. Probably my knowledge on compilers is just too little to understand what is the problem in fixing this bug.
Upvotes: 0
Reputation: 303337
This is gcc bug 47226. It's still open, and the code example still fails on gcc 5.2.0, while it compiles just fine on clang 3.6. Your code looks correct to me.
Upvotes: 4