如何从std :: vector添加删除std :: functions

问题描述

我有一个简单的C ++程序,下面注册了一些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,std::placeholders::_1));
    }

    void UnregisterAllListeners() {
        m_some_class.UnregisterListener(std::bind(&SomeOtherClass::ListenerMethod1,std::placeholders::_1));
        m_some_class.UnregisterListener(std::bind(&SomeOtherClass::ListenerMethod2,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:function中存储函数的实际地址而不是存储std::vector

解决方法

您无法比较std::functionexcept with nullptr),因此这种方法永远行不通(find无法找到您要查找的功能)。

相反,请将std::function包装到每个也具有唯一ID的类中,然后进行比较(使用find的自定义比较器)。

或者,如果您不介意进行动态分配,则可以将std::function包装在std::shared_ptr<>中,然后将它们存储/传递以进行比较。但是,请注意,在这种情况下,两个截然不同(但“相同”)的函子仍然会比较false,因此您需要仔细考虑要实现的目标以及如何使用代码。

无论哪种方式,ListenerType都应不仅仅是别名。

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...