【发布时间】:2014-01-24 08:51:55
【问题描述】:
假设有以下课程:
#include <functional>
#include <vector>
template<typename T1> class Signaler
{
public:
typedef std::function<void (T1)> Func;
public:
Signaler()
{
}
void Call(T1 arg)
{
for(Int32 i = (Int32)_handlers.size() - 1; i > -1; i--)
{
Func handler = _handlers[i];
handler(arg);
}
}
Signaler& operator+=(Func f)
{
_handlers.push_back( f );
return *this;
}
Signaler& operator-=(Func f)
{
for(auto i = _handlers.begin(); i != _handlers.end(); i++)
{
if ( (*i).template target<void (T1)>() == f.template target<void (T1)>() )
{
_handlers.erase( i );
break;
}
}
return *this;
}
private:
std::vector<Func> _handlers;
};
我使用它的方式如下:
Signaler Global::Signal_SelectionChanged;
class C1
{
public:
void Register()
{
Global::Signal_SelectionChanged += [&](SelectionChangedEventArgs* e) { this->selectionChangedEvent_cb(e); };
}
void Unregister()
{
Global::Signal_SelectionChanged -= [&](SelectionChangedEventArgs* e) { this->selectionChangedEvent_cb(e); };
}
void selectionChangedEvent_cb(SelectionChangedEventArgs* e) {}
};
class C2
{
public:
void Register()
{
Global::Signal_SelectionChanged += [&](SelectionChangedEventArgs* e) { this->selectionChangedEvent_cb(e); };
}
void Unregister()
{
Global::Signal_SelectionChanged -= [&](SelectionChangedEventArgs* e) { this->selectionChangedEvent_cb(e); };
}
void selectionChangedEvent_cb(SelectionChangedEventArgs* e) {}
};
现在,我遇到的问题是,当我从 C2 类中调用“Unregister”时,它会删除错误版本的“lambda”表达式,因为“lambda”看起来很相似。
我该如何解决这个问题?
有什么想法吗?
谢谢
【问题讨论】:
-
或许使用一些id来注销会更好?在我制作的信号管理器中,我将处理程序存储在一个列表中。 register 函数返回一个指向新处理程序的列表迭代器。 Unregister 将其作为参数并使用它来删除处理程序。另一种选择是使用整数 id 并将处理程序存储在 int => 处理程序映射中。
-
两个
std::function<T>的目标可以以您使用的方式进行有意义的比较,因此除非您发布一些相关代码显示您填充向量然后尝试删除并随后获得结果 - 所以我们有一个希望发现你的实际错误 - 这个问题是在浪费时间...... -
嗨,填充向量的代码在那里!!!调用注册/取消注册时,请参阅 C1 和 C2 类。
标签: c++ templates c++11 lambda