Cách thêm hàm remove std :: khỏi std :: vector [trùng lặp]
Tôi có một chương trình C ++ đơn giản bên dưới đăng ký một số lệnh gọi lại / người nghe chỉ là std::functions. Và sau đó nó loại bỏ các lệnh gọi lại.
Mã:
#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();
}
Câu hỏi:
Vấn đề là UnregisterListenerkhông biên dịch và không thành công với lỗi sau.
error: overload resolution selected deleted operator '=='
Tuy nhiên, đây chính xác là cách được sử dụng để tìm và xóa một mục khỏi a std::vector. Phải không? Tôi đang làm gì sai?
Nhìn chung, câu hỏi của tôi cũng là để kiểm tra xem đây có phải là cách phù hợp để thêm và xóa trình nghe trong C ++ bằng cách sử dụng std::functions không?
Xem qua cuộc thảo luận này , tôi có nên lưu trữ địa chỉ thực của hàm chứ không phải là std:functions trong std::vector?
Trả lời
Bạn không thể so sánh std::functioncác s ( ngoại trừ vớinullptr ), vì vậy cách tiếp cận đó sẽ không bao giờ hoạt động ( findkhông thể xác định chức năng bạn đang tìm kiếm).
Thay vào đó, hãy bọc lớp std::functionvào một số lớp cũng có một ID duy nhất cho mỗi lớp, sau đó so sánh lớp đó thay thế (sử dụng bộ so sánh tùy chỉnh cho find).
Ngoài ra, và nếu bạn không bận tâm một chút về phân bổ động, bạn có thể gói các std::functions vào std::shared_ptr<>và lưu trữ / chuyển chúng xung quanh để so sánh. Tuy nhiên, hãy lưu ý rằng hai hàm phân biệt (nhưng "giống hệt") sẽ vẫn so sánh sai trong trường hợp này, vì vậy bạn cần phải suy nghĩ cẩn thận về những gì bạn đang cố gắng đạt được và cách mã của bạn cần được sử dụng.
Dù bằng cách nào, ListenerTypekhông chỉ là một bí danh.