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.