模板函数将可变数量的元组元素作为参数绑定到另一个函数
Template function binding variadic number of tuple's elements to another function as arguments
在 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;
}
使用 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...>{});
}
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>>{}>{});
}
以上将支持任何 tuple-esque,即 std::array
、std::tuple
等,同时考虑占位符参数。
Demo.
在 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;
}
使用 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...>{});
}
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>>{}>{});
}
以上将支持任何 tuple-esque,即 std::array
、std::tuple
等,同时考虑占位符参数。
Demo.