相关疑难解决方法(0)

为什么std :: function不相等?

这个问题也适用于boost::functionstd::tr1::function.

std::function 不相等的平等:

#include <functional>
void foo() { }

int main() {
    std::function<void()> f(foo), g(foo);
    bool are_equal(f == g); // Error:  f and g are not equality comparable
}
Run Code Online (Sandbox Code Playgroud)

在C++ 11中,operator==operator!=重载并不存在.在早期的C++ 11草案中,使用注释(N3092§20.8.14.2)将重载声明为已删除:

// deleted overloads close possible hole in the type system
Run Code Online (Sandbox Code Playgroud)

它没有说明"类型系统中可能存在的漏洞"是什么.在TR1和Boost中,声明了重载但未定义.TR1规范评论(N1836§3.7.2.6):

这些成员函数应保持未定义.

[ 注意:类似布尔值的转换会打开一个漏洞,通过==或可以比较两个函数实例!=.这些未定义的void运算符会关闭漏洞并确保编译时错误.- 尾注 ]

我对"漏洞"的理解是,如果我们有bool转换函数,那么转换可以用于相等比较(以及其他情况):

struct S {
    operator bool() { return false; }
};

int main() { …
Run Code Online (Sandbox Code Playgroud)

c++ boost function tr1 c++11

61
推荐指数
4
解决办法
1万
查看次数

如何处理回调注册

我想实现一个回调处理程序.方法应该像以下一样简单注册......

std::multimap<Event::Type, std::function<void()>> actions;

void EventManager::registerAction(Event::Type event, std::function<void()> action) {
    actions.insert(std::make_pair(event, action));
}
Run Code Online (Sandbox Code Playgroud)

......确实按预期工作.

但这种方法的问题是,取消注册回调是不可能的......

void EventManager::deregisterAction(Event::Type event, std::function<void()> action) {
    for(auto i = actions.lower_bound(event); i != actions.upper_bound(event); ++i) {
        // if action == i->second
    }
}
Run Code Online (Sandbox Code Playgroud)

...因为无法比较绑定函数.

延迟取消注册也不起作用,因为无法验证函数对象.

void EventManager::handle(Event::Type event) {
    for(auto i = actions.lower_bound(event); i != actions.upper_bound(event); ++i) {
        if(i->second) // returns true even if the object doesn't exist anymore
            i->second();
    }
}
Run Code Online (Sandbox Code Playgroud)

那么我应该如何处理这样的实现,如何避免遇到的问题呢?

c++ function-pointers callback c++11

10
推荐指数
1
解决办法
4582
查看次数

在容器中存储boost :: function对象

我有一个KeyCallbacks 的向量:

typedef boost::function<void (const KeyEvent&)> KeyCallback
Run Code Online (Sandbox Code Playgroud)

我用它来存储按下键盘按钮时的所有监听器.我可以添加它们并将事件发送到所有回调for_each,但我不知道如何KeyCallback从我的向量中删除特定的签名.

例如,我想要这样的东西:

void InputManager::UnregisterCallback(KeyCallback callback) {
  mKeyCallbacks.erase(std::find(mKeyCallbacks.begin(), mKeyCallbacks.end(), callback));
}
Run Code Online (Sandbox Code Playgroud)

根据boost::function文档(见这里),没有比较函数对象的东西,这可以解释我上面的问题.我被困了吗?这有什么好办法吗?

(我读到boost::signals了回调机制,但它显然很慢,我希望回调可能会在一帧内被解雇几次.)

c++ boost boost-function

4
推荐指数
1
解决办法
2902
查看次数