Sco*_*tty 18 c++ bind callback weak-ptr std-function
有没有办法将std :: bind绑定到std :: weak_ptr?我想存储一个"弱函数"回调,当被调用者被销毁时,它会自动"断开连接".
我知道如何使用shared_ptr创建一个std :: function:
std::function<void()> MyClass::GetCallback()
{
return std::function<void()>(std::bind(&MyClass::CallbackFunc, shared_from_this()));
}
Run Code Online (Sandbox Code Playgroud)
但是返回的std :: function使我的对象永远保持活着.所以我想将它绑定到weak_ptr:
std::function<void()> MyClass::GetCallback()
{
std::weak_ptr<MyClass> thisWeakPtr(shared_from_this());
return std::function<void()>(std::bind(&MyClass::CallbackFunc, thisWeakPtr));
}
Run Code Online (Sandbox Code Playgroud)
但那不编译.(std :: bind将不接受weak_ptr!)有没有办法绑定到weak_ptr?
我已经找到了关于这个的讨论(见下文),但似乎没有标准的实现.存储"弱功能"的最佳解决方案是什么,特别是如果Boost不可用?
讨论/研究(所有这些都使用Boost并且没有标准化):
Nic*_*las 11
std::weak_ptr<MyClass> thisWeakPtr(shared_from_this());
return std::function<void()>(std::bind(&MyClass::CallbackFunc, thisWeakPtr));
Run Code Online (Sandbox Code Playgroud)
你永远不应该这样做.永远.
MyClass::CallbackFunc
是类的非静态成员函数MyClass
.作为非静态成员函数,必须使用有效的实例调用它MyClass
.
在整个点的weak_ptr
是,它并不一定有效.您可以通过将其转换为a来检测其有效性shared_ptr
,然后测试指针是否为NULL.由于weak_ptr
不保证始终有效,因此无法使用一个非静态成员函数.
你所做的不再有效:
std::bind(&MyClass::CallbackFunc, nullptr)
Run Code Online (Sandbox Code Playgroud)
它可以编译,但当你试图调用它时它最终会崩溃.
最好的办法是使用实际逻辑,如果weak_ptr
无效则不调用回调函数.bind
不是为了做逻辑而设计的; 它只是完全按照你的说法去做:调用函数.所以你需要使用一个合适的lambda:
std::weak_ptr<MyClass> thisWeakPtr(shared_from_this());
return std::function<void()>([thisWeakPtr]()
{
auto myPtr = thisWeakPtr.lock();
if(myPtr)
myPtr->CallbackFunc()
});
Run Code Online (Sandbox Code Playgroud)
我能够创建 std::function 的weak_pointers 并使用 clang-3.2 对其进行测试(您没有给出任何编译器限制)。
这是一个示例应用程序,它创建并测试我认为您所要求的内容:
#include <functional>
#include <memory>
#include <iostream>
typedef std::function<void(void)> Func;
typedef std::shared_ptr<Func> SharedFunc;
typedef std::weak_ptr<Func> WeakFunc;
void Execute( Func f ) {
f();
}
void Execute( SharedFunc sf ) {
(*sf)();
}
void Execute( WeakFunc wf ) {
if ( auto f = wf.lock() )
(*f)();
else
std::cout << "Your backing pointer went away, sorry.\n";
}
int main(int, char**) {
auto f1 = [](){ std::cout << "Func here.\n"; };
Execute( f1 );
auto f2 = [](){ std::cout << "SharedFunc here.\n"; };
SharedFunc sf2( new Func(f2) );
Execute( sf2 );
auto f3 = [](){ std::cout << "WeakFunc here.\n"; };
SharedFunc sf3( new Func(f3) );
WeakFunc wf3( sf3 );
Execute( wf3 );
// Scoped test to make sure that the weak_ptr is really working.
WeakFunc wf4;
{
auto f4 = [](){ std::cout << "You should never see this.\n"; };
SharedFunc sf4( new Func(f4) );
wf4 = sf4;
}
Execute( wf4 );
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出是:
~/projects/stack_overflow> clang++-mp-3.2 --std=c++11 --stdlib=libc++ weak_fun.cpp -o wf && ./wf
Func here.
SharedFunc here.
WeakFunc here.
Your backing pointer went away, sorry.
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
8553 次 |
最近记录: |