如何投射类型擦除的 std::function?
How to cast type-erased std::function?
我需要实现可观察的对象,当某些值发生变化时通知观察者。 一些观察者不需要知道该值。某些观察点已被类型擦除,但具有反射元数据来解释 void* 和读取数据。一些观察者使用类型安全的接口。
为了支持各种观察者,我将所有内容存储在std::function<void(void*)>
中。 但这需要额外的间接层(额外的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&)>
以避免这种低效率?
将可调用的观察者直接存储,而不是作为std::function
存储。然后,您可以避免双重std::function
间接(假设调用方尚未提供std::function
作为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&
。
No.
有些解决方案不涉及性病功能,但它们是疯狂的。
相关文章:
- 库函数需要一个 std::function<void(void)>,如何传入类函数?
- Confusion: decltype vs std::function
- 为什么 std::function 可以作为 std::not2 的参数?
- 'max'匹配'std::function<const int &(const int &, const int &)>'无过载
- 传递给std::function template的template参数究竟代表什么
- 将带有unique_ptr的可变 lambda 传递给 const&std::function
- 绑定派生类方法C++从实例范围之外的分隔 std::function 变量调用
- 如何在向量中删除 std::function<void()>?
- 将函数包装器转换为 std::function
- 类型擦除的std::function与虚拟函数调用的开销
- C++ std::function 对于类 exept 的所有实例都是空的(只有 Visual2019 编译器问题)
- 如果模板没有可变参数,则 Lambda 被推导出为 std::function
- 将 lambda 表达式传递给 std::function in C++
- 广义 std::function (std::any 表示可调用对象)
- std::function<std::optional<T>()> 如何与返回 T 的 lambda 兼容?
- std::function std::bind with lambda overload ambiguity
- Clang bug with std::function, std::bind and std::ref?
- 为什么我会收到编译错误"use of deleted function 'std::unique_ptr ..."
- 为什么我不能让 std::function<std::vector<T>::iterator> 绑定到返回该类型的 lambda?
- 回调(std::function/std::bind)与接口(抽象类)的优缺点