When I first mentioned return values, I said that more advanced handling of
multiple return values was possible with Marshallers
.
A Marshaller is a class that gets fed all the return values as they're returned. It can do a couple of things:
For example, if each slot
returned an int
, we could use a marshaller return
the average value as a double
. Or we could return all values in a
std::vector<int>
, or maybe stop as soon as the first slot returns 5.
As an example, here's the averaging marshaller:
class Averager { public: // we must typedef InType and OutType for the libsigc++ library typedef double OutType; typedef int InType; Averager() : total_(0), number_(0) {} OutType value() { return (double)total_/(double)number_; } // avoid integer division static OutType default_value() { return 0; } // This is the function called for each return value. // If it returns 'true' it stops here. bool marshal(InType newval) { total_ += newval; // total of values ++number_; // count of values return false; // continue emittion process }; private: int total_; int number_; };
To use this, we pass the type as an extra template argument when defining
the Signal
, eg.
sigc::signal<int, Averager> mysignal;
Now we can do:
double average_of_all_connected_slots = mysignal();
Each connected slot
will be called, its value passed to an instance of
Averager
and that Averager
's value()
will be returned.
In the downloadable examples, this is example6.cc.