我觉得bind
做到了easier创建插槽(参见“首选”语法与“可移植”语法 http://www.boost.org/doc/libs/1_52_0/doc/html/signals/tutorial.html#id3284837- 这一切都会消失)。然而,观察员管理并没有变得不那么复杂。
但作为@R.马蒂尼奥·费尔南德斯提到:std::vector<std::function< r(a1) > >
现在可以轻松创建,无需(人工)“纯虚拟”接口类的麻烦。
根据要求:关于连接管理的想法 - 可能充满错误,但你会明白的:
// note that the Func parameter is something
// like std::function< void(int,int) > or whatever, greatly simplified
// by the C++11 standard
template<typename Func>
struct signal {
typedef int Key; //
Key nextKey;
std::map<Key,Func> connections;
// note that connection management is the same in C++03 or C++11
// (until a better idea arises)
template<typename FuncLike>
Key connect( FuncLike f ) {
Key k=nextKey++;
connections[k]=f;
return k;
}
void disconnect(Key k){
connections.erase(k);
}
// note: variadic template syntax to be reviewed
// (not the main focus of this post)
template<typename Args...>
typename Func::return_value call(Args... args){
// supposing no subcription changes within call:
for(auto &connection: connections){
(*connection.second)(std::forward(...args));
}
}
};
Usage:
signal<function<void(int,int)>> xychanged;
void dump(int x, int y) { cout << x << ", " << y << endl; }
struct XY { int x, y; } xy;
auto dumpkey=xychanged.connect(dump);
auto lambdakey=xychanged.connect([&xy](int x, int y){ xy.x=x; xy.y=y; });
xychanged.call(1,2);