c++ - 如何转换类型擦除的 std::function?
问题描述
我需要实现可观察对象,当某些值发生变化时通知观察者。一些观察者不需要知道这个值。一些观察者是类型擦除的,但有反射元数据来解释 void* 和读取数据。一些观察者使用类型安全的接口。
为了支持各种观察者,我将所有内容都存储在std::function<void(void*)>
. 但这需要额外的间接层(extra std::function
)才能从类型擦除转换为类型安全接口:
template<typename T>
struct observable {
std::vector<std::function<void(void *)>> funcs;
void add_observer(std::function<void(void *)> &&f)
{
funcs.emplace_back(f);
}
void add_observer(std::function<void(T&)> &&f)
{
// extra layer of indirection
add_observer([f](void * val)
{
f(*reinterpret_cast<T*>(val));
});
}
void notify(T& new_val)
{
for (const& f : funcs) { f(&new_val); }
}
};
是否可以强制function<void(void*)>
转换function<void(T&)>
以避免这种低效率?
解决方案
将可调用的观察者直接存储而不是 as std::function
。然后你可以避免双重std::function
间接(假设调用者还没有提供std::function
as 参数add_observer
):
template<typename F>
void add_observer(F &&f)
{
funcs.emplace_back([f=std::forward<F>(f)](void * val) mutable
{
f(*static_cast<T*>(val));
});
}
请注意,如果可调用对象具有较大的状态,则将可调用对象转发到 lambda 可能会更高效,并且还请注意,这static_cast
足以转换void*
为另一个对象指针类型。
您要求的具体演员表std::function
不存在。它需要std::function
对void*
->的预期语义做出T&
根本不明显的假设。
推荐阅读
- unity3d - 难以理解 tex2Dlod 的工作原理
- c - C 指针自己的声明而不是地址
- python - 为什么我们在使用管道时不转换 X_test
- sql - SQL 基于多个条件删除行
- windows - 如何最小化_beginThreadEx创建的线程中的cpu使用率?
- python - 如何在 Z3Py 的列表中使用 Empty 方法?
- vba - 根据 ID 锁定 Access 数据库中的先前记录
- spring - Tomcat 8 + Spring @EnableAsync = 应用部署错误
- security - 禁用“编辑应用程序”按钮的 jupyter appmode 是否安全?
- ruby-on-rails - 使用 Gmail 帐户通过设备发送电子邮件失败