从Iterator对创建函数参数包

时间:2015-02-15 06:23:36

标签: c++ c++11 boost-mpl

我无法弄清楚如何使用从迭代器中检索的可变数量的参数来调用函数。我有一个使用std::plus来说明问题的简单示例:

#include <boost/mpl/placeholders.hpp>
#include <boost/mpl/apply.hpp>
#include <iostream>
#include <array>

namespace mpl = boost::mpl;

int main() {
    using OP = std::plus<mpl::_>;
    std::array<int, 2> args = {1, 2};

    // This works (passing each arg separately)
    auto n1 = mpl::apply<OP, int>::type()(args[0], args[1]);

    std::cout << "plus (1,2) = " << n1 << std::endl;

    // what I want is more like:
    // auto n2 = mpl::apply<OP, int>::type()(args);
    // or
    // auto n3 = mpl::apply<OP, int>::type()(args.begin(), args.end());
}

我无法弄清楚如何跨越这个编译时/运行时边界。感谢您的任何指示!

2 个答案:

答案 0 :(得分:1)

@PiotrS在问题评论部分的评论是正确的答案。我在下面复制了他的答案(并更新了C ++ 14 - 它清理了很多)。 @PiotrS上面回答的是C ++ 11(这就是我要求的)。

#include <boost/mpl/placeholders.hpp>
#include <boost/mpl/apply.hpp>
#include <iostream> 
#include <array>
#include <utility>

namespace mpl = boost::mpl;

template <typename OP, typename T, typename Args, std::size_t... Is>
auto apply(Args&& args, std::index_sequence<Is...>)
{
    return typename mpl::apply<OP, T>::type()(std::get<Is>(std::forward<Args>(args))...);
}

template <typename OP, typename T, typename Args, std::size_t N = std::tuple_size<std::decay_t<Args>>{}>
auto apply(Args&& args)
{
    return apply<OP, T>(std::forward<Args>(args), std::make_index_sequence<N>{});
}

int main() {
    using OP = std::plus<mpl::_>;
    std::array<int, 2> args = {1, 2};

    auto n1 = mpl::apply<OP, int>::type()(args[0], args[1]);
    std::cout << "plus (1,2) = " << n1 << std::endl;

    auto n2 = apply<OP, int>(args);
    std::cout << "plus ([1,2]) = " << n2 << std::endl;
}

此解决方案利用完美的参数转发。调用语法正是我想要的。作为奖励,此解决方案适用于任何类似于元组的参数类型(专门用于std :: get&amp; std :: tuple_size)。

感谢@PiotrS!

答案 1 :(得分:0)

std::make_index_sequence是一个很好的辅助元函数,用于此目的:

template <typename Func, typename T, size_t N, size_t... Inds>
int ApplyFuncHelper(std::array<T, N> const& arr, std::index_sequence<Inds...>)
{
 return Func()(arr[Inds]...);
}

template <typename Func, typename T, size_t N>
int ApplyFunc(std::array<T, N> const& arr)
{
 return ApplyFuncHelper<Func>(arr, std::make_index_sequence<N>());
}

Live Demo