c++ - 如何从 std::vector 添加删除 std::functions

标签 c++ c++11 stdvector std-function

这个问题在这里已经有了答案:





Comparing std::functions for equality?

(6 个回答)


去年关闭。




我在下面有一个简单的 C++ 程序,它注册了一些回调/监听器,它们只是 std::function s。然后它删除回调。
代码:

#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 在 C++ 中添加和删除监听器的正确方法。 ?
翻阅 this discussion , 我应该存储函数的实际地址而不是 std:function s 在 std::vector ?

最佳答案

你无法比较std::function s ( except with nullptr ),因此该方法永远不会起作用( find 找不到您要查找的函数)。
相反,包装 std::function进入某个类,每个类都有一个唯一的 ID,然后比较它(使用自定义比较器 find )。
或者,如果您不介意一些动态分配,您可以包装 std::function s 在 std::shared_ptr<> ,并存储/传递它们以进行比较。但是,请注意,在这种情况下,两个不同(但“相同”)的仿函数仍然会比较 false,因此您需要仔细考虑您要实现的目标以及需要如何使用您的代码。
无论哪种方式,ListenerType应该不仅仅是一个别名。

关于c++ - 如何从 std::vector 添加删除 std::functions,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63792223/

相关文章:

c++ - 当我使用DirectWrite在GDI hdc上绘制文字时,如何设置透明背景?

c++ - 使用 XAML 和 C++ 再现本地视频文件

C++11 Lambda 闭包涉及通过引用离开范围的堆栈变量是允许的,但会出现未定义的行为?

c++ - 如何找到 vector 元素的乘积?

c++ - 从 vector 中提取成员变量的数组

c++ - srand 导致我的程序卡住

c++ - 指针 vector 和值 vector 之间的差异

C++ 如何将数组作为键插入到 unordered_map 中?

c++ - 使用 SFINAE 检查模板参数继承

c++ - std::vector::pop_back 是否将其中对象的指针设置为 nullptr?