C ++:lambda中的参数包扩展失败

时间:2015-09-02 16:27:43

标签: c++ lambda c++14 variadic-templates

我正在尝试创建一种直接扩展多个参数包的方法。我创建了一个函数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。

信息 vecmat仅为using - std::array声明和嵌套std::array<std::array<A,T>,B>

2 个答案:

答案 0 :(得分:4)

这是gcc bug 47226。它仍然是开放的,代码示例仍然在gcc 5.2.0上失败,而它在clang 3.6上编译得很好。你的代码对我来说是正确的。

答案 1 :(得分:0)

我刚遇到同样的问题。没有找到一个更好的欺骗,并不想打开一个新的问题,但仍然想分享我的发现。在对类似问题的评论中,我找到了一个解决方法,将参数放在元组中,然后将其解压缩到lambda中(抱歉再也找不到链接)。但是,该解决方案需要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写为functor就像魅力一样:

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只是函数范围内匿名函子的语法糖。可能我对编译器的了解太少,无法理解修复此错误的问题。