如何从 std::vector 添加删除 std::functions
How to add an remove std::functions from a std::vector
我有一个简单的 C++ 程序,它注册了一些 callbacks/listeners,它们只是 std::function
。然后它会删除回调。
代码:
#include <iostream>
#include <functional>
#include <vector>
#include <memory>
class SomeClass {
public:
typedef std::function<void(int)> ListenerType;
std::vector<ListenerType> m_listeners;
void RegisterListener(const ListenerType& listener) {
m_listeners.push_back(listener);
}
void UnregisterListener(const ListenerType& listener) {
// This does not compile. Is this the right way to remove an std::function from va ector of std::functions?
auto position= std::find(m_listeners.begin(), m_listeners.end(), listener);
if (position != m_listeners.end()) {
m_listeners.erase(position);
}
}
};
class SomeOtherClass : public std::enable_shared_from_this<SomeOtherClass>{
public:
SomeOtherClass(SomeClass some_class) : m_some_class(some_class) {
}
void RegisterAllListeners() {
m_some_class.RegisterListener(std::bind(&SomeOtherClass::ListenerMethod1, shared_from_this(), std::placeholders::_1));
m_some_class.RegisterListener(std::bind(&SomeOtherClass::ListenerMethod2, shared_from_this(), std::placeholders::_1));
}
void UnregisterAllListeners() {
m_some_class.UnregisterListener(std::bind(&SomeOtherClass::ListenerMethod1, shared_from_this(), std::placeholders::_1));
m_some_class.UnregisterListener(std::bind(&SomeOtherClass::ListenerMethod2, shared_from_this(), std::placeholders::_1));
}
private:
SomeClass m_some_class;
void ListenerMethod1(int value) {
std::cout << "The value is: " << value << std::endl;
}
void ListenerMethod2(int value) {
std::cout << "The value is: " << value << std::endl;
}
};
int main() {
SomeClass some_class;
SomeOtherClass some_other_class(some_class);
some_other_class.RegisterAllListeners();
some_other_class.UnregisterAllListeners();
}
问题:
问题是 UnregisterListener
无法编译并因以下错误而失败。
error: overload resolution selected deleted operator '=='
但是,这正是用于从 std::vector
中查找和删除项目的方式。不是吗?我做错了什么?
总的来说,我的问题也是检查这是否是使用 std::function
s 在 C++ 中添加和删除侦听器的正确方法?
查看 this discussion,我是否必须存储函数的实际地址而不是 std::vector
中的 std:function
?
您无法比较 std::function
s (except with nullptr
),因此该方法永远行不通(find
无法找到您要查找的函数)。
相反,将 std::function
包装到一些 class 中,每个 class 也有一个唯一的 ID,然后比较它(对 find
使用自定义比较器)。
或者,如果您不介意一点动态分配,您可以将 std::function
包装在 std::shared_ptr<>
中,然后将 store/pass 包装在周围进行比较。但是,请注意,在这种情况下,两个不同(但“相同”)的仿函数仍然会比较 false,因此您需要仔细考虑您要实现的目标以及需要如何使用您的代码。
无论如何,ListenerType
不应该只是一个别名。
我有一个简单的 C++ 程序,它注册了一些 callbacks/listeners,它们只是 std::function
。然后它会删除回调。
代码:
#include <iostream>
#include <functional>
#include <vector>
#include <memory>
class SomeClass {
public:
typedef std::function<void(int)> ListenerType;
std::vector<ListenerType> m_listeners;
void RegisterListener(const ListenerType& listener) {
m_listeners.push_back(listener);
}
void UnregisterListener(const ListenerType& listener) {
// This does not compile. Is this the right way to remove an std::function from va ector of std::functions?
auto position= std::find(m_listeners.begin(), m_listeners.end(), listener);
if (position != m_listeners.end()) {
m_listeners.erase(position);
}
}
};
class SomeOtherClass : public std::enable_shared_from_this<SomeOtherClass>{
public:
SomeOtherClass(SomeClass some_class) : m_some_class(some_class) {
}
void RegisterAllListeners() {
m_some_class.RegisterListener(std::bind(&SomeOtherClass::ListenerMethod1, shared_from_this(), std::placeholders::_1));
m_some_class.RegisterListener(std::bind(&SomeOtherClass::ListenerMethod2, shared_from_this(), std::placeholders::_1));
}
void UnregisterAllListeners() {
m_some_class.UnregisterListener(std::bind(&SomeOtherClass::ListenerMethod1, shared_from_this(), std::placeholders::_1));
m_some_class.UnregisterListener(std::bind(&SomeOtherClass::ListenerMethod2, shared_from_this(), std::placeholders::_1));
}
private:
SomeClass m_some_class;
void ListenerMethod1(int value) {
std::cout << "The value is: " << value << std::endl;
}
void ListenerMethod2(int value) {
std::cout << "The value is: " << value << std::endl;
}
};
int main() {
SomeClass some_class;
SomeOtherClass some_other_class(some_class);
some_other_class.RegisterAllListeners();
some_other_class.UnregisterAllListeners();
}
问题:
问题是 UnregisterListener
无法编译并因以下错误而失败。
error: overload resolution selected deleted operator '=='
但是,这正是用于从 std::vector
中查找和删除项目的方式。不是吗?我做错了什么?
总的来说,我的问题也是检查这是否是使用 std::function
s 在 C++ 中添加和删除侦听器的正确方法?
查看 this discussion,我是否必须存储函数的实际地址而不是 std::vector
中的 std:function
?
您无法比较 std::function
s (except with nullptr
),因此该方法永远行不通(find
无法找到您要查找的函数)。
相反,将 std::function
包装到一些 class 中,每个 class 也有一个唯一的 ID,然后比较它(对 find
使用自定义比较器)。
或者,如果您不介意一点动态分配,您可以将 std::function
包装在 std::shared_ptr<>
中,然后将 store/pass 包装在周围进行比较。但是,请注意,在这种情况下,两个不同(但“相同”)的仿函数仍然会比较 false,因此您需要仔细考虑您要实现的目标以及需要如何使用您的代码。
无论如何,ListenerType
不应该只是一个别名。