如何更改参数包中的最后一个参数?

fac*_*tus 7 c++ templates variadic-templates generic-lambda c++14

我有一个功能 f1()

template <typename... Args>
void f1(Args... args)
{
    // the implementation is just an example, I don't really need a complicated
    // way to sum numbers
    boost::fusion::vector<Args...> v(args...);
    std::cout << boost::fusion::accumulate(v, 0, [](auto i1, auto i2) { return i1 + i2; }) << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

我想从函数中调用它f2(),但是使用不同的最后一个参数.有一个简单的方法吗?我尝试了一个天真的

template <typename... Args>
struct CallHelper;

template <>
struct CallHelper<>
{
    template <typename... Args>
    static void Apply(Args... args) { f1(args...); }
};

template <typename A0>
struct CallHelper<A0>
{
    template <typename... Args>
    static void Apply(Args ...args, A0 a0)
    {
        // substitute 10 to the last argument
        CallHelper<>::Apply(args..., 10);
    }
};

template <typename Head, typename ...TailArgs>
struct CallHelper<Head, TailArgs...>
{
    template <typename... Args>
    static void Apply(Args... args, Head head, TailArgs ...tailArgs)
    {
        CallHelper<TailArgs...>::Apply(args..., head, tailArgs...);
    }
};

template <typename... Args>
void f2(Args... args)
{
    CallHelper<Args...>::Apply(args...);
}
Run Code Online (Sandbox Code Playgroud)

当然它不起作用,因为Head head它不是第一个参数.也许还有办法制作Head head参数包?或者还有其他我可以做的事情?

Ser*_*gey 5

您可以将参数转发为元组,然后解压缩除最后一个之外的所有参数std::integer_sequence.此代码看起来比您的方法简单得多:

template<typename... Args>
void f1(Args... args)
{
    boost::fusion::vector<Args...> v(args...);
    std::cout << boost::fusion::accumulate(v, 0, [](auto i1, auto i2) { return i1 + i2; }) << std::endl;
}

template<typename Tuple, size_t... idx>
void callImpl(Tuple&& tuple, std::index_sequence<idx...>)
{
    f1(std::get<idx>(std::forward<Tuple>(tuple))..., 10);
}

template<typename... Ts>
void callWithLast10(Ts&&... ts)
{
    callImpl(std::forward_as_tuple(ts...), std::make_index_sequence<sizeof...(Ts) - 1>());
}
Run Code Online (Sandbox Code Playgroud)

用法:

f1(1, 2, 3, 4); // Prints 10
callWithLast10(1, 2, 3, 4); // Prints 16
Run Code Online (Sandbox Code Playgroud)