将迭代器的左侧从auto替换为pair

Replacing left side of iterator from auto to pair

本文关键字:auto 替换 pair 迭代器      更新时间:2023-10-16

我试图修改代码从http://juanchopanzacpp.wordpress.com/2013/02/24/simple-observer-pattern-implementation-c11/

我给registerObserver添加了一个参数:

void registerObserver( Event&& event, Observer&& observer, 
                       std::string identifier )

那么地图现在是

std::map<Event, ObserverPair> 

,

typedef std::pair< std::string, 
                   std::vector< std::function<void( )> > > ObserverPair;

但是,现在我不知道如何正确地修改这一行:

for (const auto& obs : observers_.at(event)) obs();

如何替换它来调用pair中的第二个元素?因为观察者现在在那里。

编辑:

好吧,这可能是最好的解决方案(在下面的评论中指出),没有标识符,只是使用对观察者的引用从向量中删除它。我创建了这个函数:

template <typename Observer>
void removeObserver( Event&& event, Observer&& observer )
{
  observers_[std::move( event )]
    .erase( std::remove(  observers_[event].begin( ),
                          observers_[event].end( ),
                          std::forward<Observer>( observer ) ), 
            observers_[event].end( ) );
}

但是当我调用"input->removeObserver("test", std::bind(bar));"

错误:

Error   1   error C2679: binary '==' : no operator found which takes a right-hand operand of type 'const std::_Bind<true,void,void (__cdecl *const )(void),>' (or there is no acceptable conversion)

你知道怎么解决这个问题吗?

observers_.at(event)现在给你一对而不是一个向量。向量是该对的第二个元素,因此您应该将observers_.at(event)替换为observers_.at(event).second来访问它:

for (const auto& obs : observers_.at(event).second) obs();

这些是你应该做的修改,以增加移除观察者的能力,尽可能地解除观察者的耦合:

template <class Callable>
void registerObserver(const Event& event,
    Callable&& callback, const void* tag = &callback)

我从event中删除了move语义,因为您既不希望也不需要它们。
请注意回调是一个通用引用。
我将标识符/标签更改为void*,并为回调是标签的情况添加了默认值。
使用:
event:您想要注册的事件。
callback:通知可调用项。如果std::move是临时的,则显式使用。
- tag:观察者对象通知或一些其他好的标签。如果observer-object相同,默认为callback

void removeObserver( const Event& event, void* vp)
{
    observers_[event].remove_if(
        [](ObserverPair& x){return x.second == vp});
}