C++:lambda 中的参数包扩展失败
C++: parameter pack expansion inside lambda fails
我正在尝试创建一种直接扩展多个参数包的方法。我创建了一个函数 template<size_t X,typename F> auto sequenceFunc(F&& f)
,它调用给定函数 f
并扩展 integer_sequence
.
这适用于像这样的小函数:
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]
});
}
不幸的是我不能展开多个参数包,即使我遵循规则,一个 ...
表达式中只能有一个参数包。
这是我尝试使用此函数进行矩阵乘法:
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
};
});
}
这是错误:
error: parameter packs not expanded with '...':
auto i = I;
^
我真的不明白为什么需要扩展,因为表达式之外还有另一个...
。我使用 GCC 5.1.0.
信息 vec
和 mat
只是 using
对 std::array
和嵌套 std::array<std::array<A,T>,B>
的声明
这是gcc bug 47226。它仍然是打开的,代码示例在 gcc 5.2.0 上仍然失败,而在 clang 3.6 上编译得很好。你的代码在我看来是正确的。
我刚遇到同样的问题。没有找到更好的骗子,也不想提出新问题,但仍想分享我的发现。在对类似问题的评论中,我发现了一种解决方法,将参数放在一个元组中,然后将其解压缩到 lambda 中(抱歉,再也找不到 link 了)。但是,该解决方案需要 C++17(std::apply
及更多)。
我的情况是这样的:
struct Foo{
template <typename T,typename ...ARGS>
void foo(T t,ARGS...args){
auto x = [&](){ t(args...);}
}
};
不适用于 gcc 4.8.5。令我惊讶的是,简单地显式写出 lambda 作为仿函数就像一个魅力:
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...>();
}
};
我觉得有点奇怪,gcc吞下了这个,而不是第一个。 Afaik lambdas 只是函数范围内匿名仿函数的语法糖。可能我对编译器的了解太少,无法理解修复此错误的问题。
我正在尝试创建一种直接扩展多个参数包的方法。我创建了一个函数 template<size_t X,typename F> auto sequenceFunc(F&& f)
,它调用给定函数 f
并扩展 integer_sequence
.
这适用于像这样的小函数:
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]
});
}
不幸的是我不能展开多个参数包,即使我遵循规则,一个 ...
表达式中只能有一个参数包。
这是我尝试使用此函数进行矩阵乘法:
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
};
});
}
这是错误:
error: parameter packs not expanded with '...':
auto i = I;
^
我真的不明白为什么需要扩展,因为表达式之外还有另一个...
。我使用 GCC 5.1.0.
信息 vec
和 mat
只是 using
对 std::array
和嵌套 std::array<std::array<A,T>,B>
的声明
这是gcc bug 47226。它仍然是打开的,代码示例在 gcc 5.2.0 上仍然失败,而在 clang 3.6 上编译得很好。你的代码在我看来是正确的。
我刚遇到同样的问题。没有找到更好的骗子,也不想提出新问题,但仍想分享我的发现。在对类似问题的评论中,我发现了一种解决方法,将参数放在一个元组中,然后将其解压缩到 lambda 中(抱歉,再也找不到 link 了)。但是,该解决方案需要 C++17(std::apply
及更多)。
我的情况是这样的:
struct Foo{
template <typename T,typename ...ARGS>
void foo(T t,ARGS...args){
auto x = [&](){ t(args...);}
}
};
不适用于 gcc 4.8.5。令我惊讶的是,简单地显式写出 lambda 作为仿函数就像一个魅力:
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...>();
}
};
我觉得有点奇怪,gcc吞下了这个,而不是第一个。 Afaik lambdas 只是函数范围内匿名仿函数的语法糖。可能我对编译器的了解太少,无法理解修复此错误的问题。