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.