C++ c++;11:比较lambda表达式
想象一下,我们有以下课程:C++ c++;11:比较lambda表达式,c++,templates,c++11,lambda,C++,Templates,C++11,Lambda,想象一下,我们有以下课程: #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)_ha
#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;
};
现在,我遇到的问题是,当我从C2类调用“Unregister”时,它删除了错误版本的“lambda”表达式,因为“lambda”看起来很相似
我怎样才能解决这个问题
有什么想法吗
谢谢问题是您使用的
std::function::target
类型与std::function
中存储的对象类型不同,因此它返回空指针。也就是说,您需要知道std::function
中存储的对象的实际类型,以便能够调用target
>
即使使用用于添加回调的lambda闭包类型调用target
,这也不起作用,原因有二:首先,lambda闭包类型是唯一的(5.1.2p3)因此+=
和-=
lambda具有不同的类型,即使它们在语法上相同;其次,lambda表达式的闭包类型没有定义为具有运算符==
(5.1.2p3-6,19-20),因此您的代码甚至不会编译
从lambdas切换到std::bind
没有帮助,因为绑定类型也没有定义为具有operator==
而不是使用ID来登记/取消回调。您也可以使用自己的函数定义了<代码>运算符==/COD>,但是这将是一项很大的工作。< / P>也许最好使用一些ID来取消注册。在我所做的一个信号管理器中,我把处理程序存储在一个列表中。登记函数返回一个列表迭代器Pin。ting到新的处理程序。Unregister将其作为参数并使用它删除处理程序。另一个选项是使用整数id并将处理程序存储在int=>处理程序映射中。来自两个
std::function
的目标可以以您使用的方式进行有意义的比较,因此除非您发布一些相关代码显示填充vector然后尝试删除,然后得到结果-因此我们有希望发现您的实际错误-这个问题是在浪费时间…嗨,填充向量的代码在那里!!!调用Register/Unregister时,请参阅类C1和C2。
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) {}
};