如何向std::vector添加或删除std::function。

4

我下面有一个简单的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, 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++ 中添加和删除监听器的正确方法?

通过查看这个讨论,我是否必须存储函数的实际地址而不是 std:functionstd::vector中?


请将以下与编程有关的内容从英语翻译成中文。仅返回已翻译的文本:请在问题中包含编译器错误。 - 463035818_is_not_a_number
"不会编译"。哪里出了错? - Asteroids With Wings
1个回答

2

您不能比较std::function除了nullptr),因此该方法永远不会起作用(find无法找到您要查找的函数)。

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

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

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


1
将std::function包装到某个类中?有没有我可以参考的示例?或者你能在我已有的代码中给出一个简短的示例吗?显然,如何正确地做到这一点也是我在这里提问的目的。 - TheWaterProgrammer
我相信你的书会教你如何编写一个类 :) 实际上,你已经在上面做了两次! - Asteroids With Wings
1
好的好的!我会从标记的另一个问题中找到答案。 - TheWaterProgrammer
1
非常优雅的方法。 - Hatted Rooster
@SombreroChicken 谢谢!我自己打的。 - Asteroids With Wings

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接