绑定到C++中参数数量未知的函数
Bind to function with an unknown number of arguments in C++
假设我有一个std::function
,它接受类型为T
的N
参数作为输入(这可以使用一些元编程魔术来构建;请参见下文),其中N
是一个模板参数。我想用std::bind
作为第一个参数来构造具有N-1
参数的函数(例如myBind<...>(someValue)
)。我想不出有什么聪明的元编程技巧可以做到这一点。有什么建议吗?
来自Lambda函数,其参数数在编译时确定:
您可以编写具有嵌套
typedef
类型的模板n_ary_function
。这种类型可以按如下方式使用:template <int N> class A { typename n_ary_function<N, double>::type func; };
遵循
n_ary_function
:的定义template <std::size_t N, typename Type, typename ...Types> struct n_ary_function { using type = typename n_ary_function<N - 1, Type, Type, Types...>::type; }; template <typename Type, typename ...Types> struct n_ary_function<0, Type, Types...> { using type = std::function<void(Types...)>; };
std::bind
使用std::is_placeholder
来检测占位符,这意味着您可以通过部分专用化std::is_placeholder
:来编写自己的占位符以与std::bind
一起使用
template<int N>
struct my_placeholder { static my_placeholder ph; };
template<int N>
my_placeholder<N> my_placeholder<N>::ph;
namespace std {
template<int N>
struct is_placeholder<::my_placeholder<N>> : std::integral_constant<int, N> { };
}
这使得从整数中获取占位符成为可能。剩下的只是标准的整数序列技巧:
template<class R, class T, class...Types, class U, int... indices>
std::function<R (Types...)> bind_first(std::function<R (T, Types...)> f, U val, std::integer_sequence<int, indices...> /*seq*/) {
return std::bind(f, val, my_placeholder<indices+1>::ph...);
}
template<class R, class T, class...Types, class U>
std::function<R (Types...)> bind_first(std::function<R (T, Types...)> f, U val) {
return bind_first(f, val, std::make_integer_sequence<int, sizeof...(Types)>());
}
演示。std::integer_sequence
在技术上是C++14,但它在C++11中很容易实现——只需在SO上搜索即可。
#include <functional>
#include <cstddef>
#include <utility>
#include <tuple>
template <std::size_t N, typename Type, typename... Types>
struct n_ary_function
{
using type = typename n_ary_function<N - 1, Type, Type, Types...>::type;
};
template <typename Type, typename... Types>
struct n_ary_function<0, Type, Types...>
{
using type = std::function<void(Types...)>;
};
using placeholders_list = std::tuple<decltype(std::placeholders::_1)
, decltype(std::placeholders::_2)
, decltype(std::placeholders::_3)
, decltype(std::placeholders::_4)
, decltype(std::placeholders::_5)
, decltype(std::placeholders::_6)
, decltype(std::placeholders::_7)
, decltype(std::placeholders::_8)
, decltype(std::placeholders::_9)
, decltype(std::placeholders::_10)
>;
template <typename F>
struct arity;
template <typename R, typename... Args>
struct arity<std::function<R(Args...)>>
{
static constexpr std::size_t value = sizeof...(Args);
};
template <typename F, typename T, std::size_t... Ints>
auto binder(F f, T t, std::index_sequence<Ints...>)
{
return std::bind(f, t,
typename std::tuple_element<Ints, placeholders_list>::type{}...);
}
template <typename F, typename T>
auto myBind(F f, T t)
{
return binder(f, t, std::make_index_sequence<arity<F>::value - 1>{});
}
测试:
#include <iostream>
void foo(int a, int b, int c, int d, int e)
{
std::cout << a << b << c << d << e << std::endl;
}
int main()
{
n_ary_function<5, int>::type f = foo;
n_ary_function<4, int>::type b = myBind(f, 1);
b(2, 3, 4, 5);
}
DEMO
相关文章:
- 双链表的擦除值函数,未知错误
- 在带有模板的函数中传递未知大小的 std::数组.如何更正此代码?
- 如何创建参数数量未知的函数?
- 通过 C++ 中的重载构造函数初始化未知类型的变量
- 线程 std::调用未知类型,无法专门化函数错误
- 参数数据类型未知的可变参数函数
- 通过模板函数对未知类型调用方法
- 在回调中使用函数时,C++未知重写说明符
- 在库的未知类中调用函数
- 当数组大小在C++中未知时,如何在运行时将对字符串数组的引用作为函数参数传递?
- 如何获取指向未知重载函数的任何重载的指针?
- 在 C++ 的模板函数中初始化自动(未知)类型的向量
- GCC 升级导致模板函数的静态局部变量变得未知
- 使用来自C++的任意数量的参数(在编译时未知)调用 Python 函数
- 断言失败<dst.data != src.data >在未知函数中。/../ocv/opencv/modules/imgproc/src/imgwarp.cpp
- 断言失败 <0 <= i && i < <int>vv.size<>> 在未知函数中,文件 src\matrix.cpp,第 912 行
- 协助添加未知函数.(C++)
- 如何从动态库中调用未知函数
- 在未知函数中断言失败
- OpenCV 2.2:未知函数中的错误参数,文件.. .ocv OpenCV modulescoresr