实现信号(观察者模式):是必需的还是const_cast?

rub*_*nvb 12 c++ signals-slots observer-pattern c++11

我正在实现我自己的signal/ slot(观察者模式,Qt样式)机制,所以我可以property通知......那些已经改变了.

我认为C++ 11提供了所有必要的功能,可以实现非常简洁和功能强大的实现.我遇到的"问题"是如果我想"连接"到const对象的信号,我需要将signal::connect函数设置为const,但修改回调/观察者列表.有两种直接解决方法:

  1. const_cast里面的清单connect.
  2. 制作清单mutable.

在我看来,两者都是相同的东西(之前已经问过这个问题,例如这个问题中),并且在逻辑上非常精细,但风格上有问题.因此问题.有没有办法绕过这个或这是一个真正合理的使用const_cast/ mutable

我现在有一些prelimenary代码:

template<typename... ArgTypes>
class signal
{
public:
  template<typename Callable>
  void connect(Callable&& callback) const
  {
    std::lock_guard<std::mutex> lock(slots_mutex);
    slots.emplace_back(callback);
  }

  void emit(ArgTypes... arguments) const
  {
    std::lock_guard<std::mutex> lock(slots_mutex);
    for(auto&& callback : slots)
    {
      callback(arguments...);
    }
  }

private:
  // mutable here allows to connect to a const object's signals
  mutable std::vector<std::function<void(ArgTypes...)>> slots;
  std::mutex slots_mutex;

};
Run Code Online (Sandbox Code Playgroud)

注意我还没有测试过这段代码; 这只是我当前心态的反映.

πάν*_*ῥεῖ 9

mutable 这种情况通常是更好的选择.

const尽可能避免()转换,它很容易遇到未定义的行为,但mutable保证不是1).


例如,保证1 名成员不会去发射代码段. mutable.text