
Timmo Stange wrote:
Peter Dimov wrote:
The slot_call_iterator idiom is another thing that I don't like in the original Signals design; it feels too clever for its own good, and is there to support a nice way of using combiners. I've nothing against combiners per se, but the majority of the signal uses do not involve slot returns or combinations thereof.
If I had to redesign the library, I'd explore a simple void operator() that just calls the slots, and a separate
template<class Cm> void call_and_combine( Cm & cm, ... );
that calls cm( s( ... ) ) for each slot s.
Actually, a slightly better interface would be
template
That's what the documentation describes as the "push method" and is probably also with what I had come up with as a combiner solution, mostly because I personally wouldn't use combiners that often.
Indeed. According to the docs, there are two downsides to the push method: the need to keep state and the inability to abort the invocation. The first is solved with using an 'accumulate-like' call_and_combine or with using bind(). int max( int x, int y ) // std::max<int> is overloaded :-/ { return x < y? y: x; } int r = signal.call_and_combine( max, INT_MIN ); // or void max( int & x, int y ) { if( x > y ) x = y; } int r = INT_MIN; signal.call_and_combine( bind( max, ref( r ), _1 ) ); The second can be solved with designating a "signal abort" exception. void max_until_K( int & x, int y, int K ) { if( x > y ) x = y; if( x > K ) throw signal_abort(); } int r = INT_MIN; signal.call_and_combine( bind( max, ref( r ), _1, 100 ) ); This allows reusing the same signal with different combiners and parameters, which is probably an academic advantage. Finally, there's always the option of just giving the users a copy of the slots and letting them obtain and combine the results at their own pace. :-)