在递归函数中解压缩可变参数包时编译错误

时间:2017-11-02 10:57:32

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

让我们使用以下代码创建一个元组树和一个n-ary运算符来聚合特定级别的值:

#include <tuple>

template<class O, class... I>
struct Compose
{
    using ITuple = std::tuple<I...>;

    Compose(O&& o, I&&... i) :
        o(std::forward<O>(o)),
        i(std::forward<I>(i)...)
    { }

    float operator ()(float x) const
    { /* return o(i1(x), i2(x), i3(x), ... ); */ }

    template<unsigned H1, unsigned H2, unsigned... Ts>
    decltype(auto) getI()
    { return std::get<H1>(i).getI<H2, Ts...>(); }

    template<unsigned H>
    decltype(auto) getI()
    { return std::get<H>(i); }

    O o;
    ITuple i;
};

template<class O, class... I>
Compose<O, I...>
make_compose(O&& o, I&&... i)
{ return Compose<O, I...>(std::forward<O>(o), std::forward<I>(i)...); }

struct Foo {
    Foo(float param) : p(param) { }

    float operator()(float v) const
    { return p * v; }

    float p;
};

int main()
{
    auto out = [](float x, float y) { return x + y; };
    auto c1 = make_compose(out, make_compose(out, Foo(2), Foo(3)), Foo(4));
    auto test1 = c1.getI<0, 1>();
    test1(1); // will return 3
    return 0;
}

我正在使用-std = C ++ 14进行编译,当我使用GCC 6.4时,它编译得很好。但是对于clang ++ 3.9,它失败并出现错误:

  

错误:表达式包含未展开的参数包&#39; Ts&#39;
  { return std::get<H1>(i).getI<H2, Ts...>(); }

有谁知道真正的问题在哪里,因为它看起来像是可变参数包的明显扩展。方法getI()通过该树级别的索引返回树中的元素。

我找到了方法getI<>()的解决方法,它将元组元素传递给帮助函数doGetI()在clang中工作,但看起来很乱:

template<unsigned... Ts>
decltype(auto) getI()
{ return doGetI<Compose2, Ts...>(*this); }

template<class T, unsigned H1, unsigned H2, unsigned... Ts>
decltype(auto) doGetI(T& t)
{ return doGetI<std::tuple_element_t<H1, typename T::ITuple>, H2, Ts...>(std::get<H1>(t._i)); }

template<class T, unsigned H>
decltype(auto) doGetI(T& t)
{ return std::get<H>(t._i); }

0 个答案:

没有答案