模板函数将元组元素的可变参数数量绑定到另一个函数作为参数

时间:2016-01-12 13:19:47

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

在c ++ 11/14中是否有任何方法可以像这样编写可变参数模板函数:

template <typename ReturnType, typename Args...>
std::function<ReturnType()> bindArgumentsFromTuple
                                  (std::function<ReturnType(Args... args)> f,
                                  const std::tuple<Args...>& t)

将元组t的元素绑定到函数f作为参数(这样元素的数量及其类型在函数参数和元组中是相同的)?

使用示例:

void dummy_print(int i, double d)
{
    std::cout << i << "," << d << '\n';
}
void dummy_print2(int i, double d, std::string& s)
{
    std::cout << i << "," << d <<  "," << s << '\n';
}

int main() {
    std::tuple<int,double> t(77,1.1);
    std::tuple<int,double,std::string> t2(1,2.0,"aaa");
    auto f1 = bindArgumentsFromTuple(dummy_print, t);
    f1();
    auto f2 = bindArgumentsFromTuple(dummy_print2, t2);
    f2();

    return 0;
}

2 个答案:

答案 0 :(得分:3)

template <typename F, typename T, std::size_t... indices>
auto bindTuple(F&& f, T&& t, std::index_sequence<indices...>) {
    return std::bind(std::forward<F>(f), std::get<indices>(std::forward<T>(t))...);
}

template <typename F, typename T>
auto bindTuple(F&& f, T&& t) {
    return bindTuple(std::forward<F>(f), std::forward<T>(t),
                   std::make_index_sequence<std::tuple_size<std::decay_t<T>>{}>{});
}

上述内容将支持任何元组式,即std::arraystd::tuple等,同时考虑占位符参数。 Demo

答案 1 :(得分:1)

使用std::index_sequence,您可以执行以下操作:

template <typename ReturnType, typename ...Args, std::size_t ... Is>
std::function<ReturnType()>
bindArgumentsFromTuple_impl(std::function<ReturnType(Args...)> f,
                       const std::tuple<Args...>& t, std::index_sequence<Is...>)
{
    return [=]() { return f(std::get<Is>(t)...);};
}

template <typename ReturnType, typename ...Args>
std::function<ReturnType()>
bindArgumentsFromTuple(std::function<ReturnType(Args...)> f,
                       const std::tuple<Args...>& t)
{
    return bindArgumentsFromTuple_impl(f, t, std::index_sequence_for<Args...>{});
}

Live Demo