如何解决使用带参数包的成员函数指针
template<typename Callback,typename Callee,typename... Args>
std::function<void(Args...)> safe_bind(Callback callback,std::shared_ptr<Callee> shared) {
std::weak_ptr<Callee> weak = shared;
return std::function<void(Args...)>([callback,weak](Args... args){
if(auto shared_ptr = weak.lock()) {
// std::bind(callback,ptr)(args...);
// callback(ptr,args...);
(shared_ptr.get()->*callback)(args...);
}
});
}
这个函数类似于std::bind
,但是当绑定对象被销毁时,返回的函数可以安全地调用。
它无法编译,因为无法推导出 Args
。我想关联 Callback = void(Args...)
。但是,我找不到将 Callback
替换为带有参数包的 std::function 或函数指针类型的方法。
safe_bind(Callback callback,std::shared_ptr<Callee> shared) { // does not compile
safe_bind(void(*)(Callee*,Args...) callback,std::shared_ptr<Callee> shared) { // does not compile
safe_bind((void(*)(Callee*,Args...)) callback,std::shared_ptr<Callee> shared) {// does not compile
...
如何实现?
callback
将主要是 &Class::method
,因此最好使用没有 std::function
的解决方案(如果可能)以避免分配。
解决方法
只是不要将 lambda 包装在 std::function
中并使用任何参数类型的完美转发。您还可以使用 std::invoke
处理其他可调用对象,它会自动处理带有 operator()
的指针成员(-函数)、函数和对象:
template<typename Callback,typename Callee>
auto safe_bind(Callback&& callback,std::shared_ptr<Callee> shared) {
return [weak = std::weak_ptr{shared},callback = std::forward<Callback>(callback)](auto&&... args) {
if (auto shared_ptr = weak.lock()) {
std::invoke(callback,*shared_ptr,std::forward<decltype(args)>(args)...);
}
};
}
如果函数总是指向成员函数的指针,你可以从指针推导出参数的类型:
template<typename Callee,typename Res,typename... Args>
auto safe_bind(Res (Callee::* callback)(Args...),std::shared_ptr<Callee> shared) {
return [weak = std::weak_ptr<Callee>{shared},callback](Args... args) {
if (auto shared_ptr = weak.lock()) {
// The std::forward here moves arguments that are passed by value
((*shared_ptr).*callback)(std::forward<Args>(args)...);
}
};
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。