Comment ajouter une suppression de fonctions std :: à partir d'un std :: vector [duplicate]
J'ai un programme C ++ simple ci-dessous qui enregistre quelques callbacks / écouteurs qui ne sont que des std::functions. Et puis il supprime les rappels.
Code:
#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();
}
Question:
Le problème est qu'il UnregisterListenerne se compile pas et échoue avec l'erreur suivante.
error: overload resolution selected deleted operator '=='
Mais, c'est exactement la manière utilisée pour rechercher et supprimer un élément d'un fichier std::vector. N'est-ce pas? Qu'est-ce que je fais mal?
Dans l'ensemble, ma question est également de vérifier si c'est la bonne façon d'ajouter et de supprimer des écouteurs en C ++ en utilisant std::functions?
En parcourant cette discussion , devrais-je avoir à stocker l'adresse réelle de la fonction plutôt que le std:functions dans le std::vector?
Réponses
Vous ne pouvez pas comparer std::functions ( sauf avecnullptr ), donc cette approche ne fonctionnera jamais ( findimpossible de localiser la fonction que vous recherchez).
Au lieu de cela, enveloppez le std::functiondans une classe qui a également un ID unique pour chacun, puis comparez-le à la place (en utilisant un comparateur personnalisé pour find).
Sinon, et si cela ne vous dérange pas un peu d'allocation dynamique, vous pouvez envelopper les std::functions std::shared_ptr<>et les stocker / les transmettre pour les comparer. Cependant, sachez que deux foncteurs distincts (mais "identiques") se compareraient toujours à false dans ce cas, vous devez donc réfléchir attentivement à ce que vous essayez de réaliser et à la manière dont votre code doit être utilisé.
Quoi qu'il en soit, cela ListenerTypedevrait être plus qu'un simple alias.