按值传递 std::function<bool (int)>
Passing std::function<bool (int)> by value
我试图暴露
typedef std::function<bool (int)> Filter;
那是的一部分
#include <functional>
以便用户可以创建Filter并将其传递到我的组件中进行处理。该需求要求处理不能在模板化函数中完成。
我知道在接口上使用STL不是一个好的做法,因为Filter类型的大小取决于STL实现。除了原始函数指针或模板函数接收的函子之外,我的其他选项是什么。
如果尺寸在这里不是很重要,但如果使用您库的某个库使用不同的STL实现,那么它将无法使用您的代码,那么还有什么选择呢?我将为此使用一个接口(纯虚拟类):
struct MyCallback {
virtual bool filter( int ) = 0;
};
class MyImplementation {
public:
...
void set_callbacks( MyCallback* );
};
使用这个体系结构,您可以让您的用户使用C++的强大功能,同时您不依赖STL!
您可以将函数指针作为std::bind
的结果传递。例如:
typedef std::function<bool (int)> Filter;
bool Foo(int i)
{
return i == 0;
}
void BarCaller(Filter bar) //pass by value
{
bar(2);
}
Filter bar = std::bind(&Foo, std::placeholders::_1); //now you can pass bar wherever you want
BarCaller(bar);
因此,如果您希望dll接口保持C风格,请提供一种方法将std::function
封装在该对中。类似于:
bool c_style_callback(void *userdata, int n) {
return (*static_cast<const Filter*>(userdata))(n);
}
您可以在头文件中提供一个方便的函数,该函数在调用dll中运行,并提供您真正想要的接口:
inline void register_callback(const Filter &filter) {
register_c_style_callback(c_style_callback, static_cast<void*>(&filter));
}
我一直很懒惰,并让调用者负责确保filter
在回调注册期间保持有效。您可以通过动态分配它的副本,并添加代码来在取消注册回调时检索和释放它(同样,此代码在调用dll中运行)来解决此问题。如果取消注册是由调用者发起的,那么您需要某种表示已注册回调的句柄。
如果Filter
是一个传递给算法的谓词,而该算法在返回后不再使用它,那么懒惰就会得到回报。只有当过滤器被无限期注册时,您才需要一个完整的机制来管理生存期。
相关文章:
- 为什么在全局范围内使用"extern int a"似乎不行?
- int(c) 和 c-'0' 之间的区别。C++
- 从"int*"强制转换为"unsigned int"会丢失精度错误
- 为什么野牛仍在使用"int yylex(void)",却找不到"int yylex(YYS
- 有符号的int和int-有没有一种方法可以在C++中区分它们
- 请解释这句话(cout<<1+int((a<b)^((b-a)&1) )<<endl
- 是否可以从int转换为enum类类型
- 不能在初始值设定项列表中将非常量表达式从类型 'int' 缩小到'unsigned long long'
- 向量 <int> a {N, 0} 和 int arr a[N] = {0} 的时间复杂度有什么区别
- 'short int'持有的值溢出,但"自动"不会溢出?
- 如何在C++中将一个无符号的 int 转换为两个无符号的短裤?
- 调用'begin(int [n])'没有匹配函数
- 没有显式声明的int[]中的foreach
- 在c++中访问int到类对象的映射时出错
- 为什么我无法更改"set<set>"循环中的值<int>
- EASTL矢量<向量<int>>连续的
- 为什么将此对向量&lt; map&lt; int,int&gt;&gt;中的地图进行更新.失败
- 如何加入向量&lt; int&gt;到C 中的单个INT
- 是numeric_limits&lt; int&gt; :: is_modulo从逻辑上矛盾
- 'structstd::对<int,int>'没有名为'push_back'