Re: Polymorphic Accumulate
helix wrote:
Hi,
Is it possible to use polymorphic classes as 'accumulators'? Consider
the situation where I want to accumulate over a vector, but the user
has the option to decide what 'function' is used. Hence, I have a Base
class (itself a binary_function) from which two classes are extended
(Add and Subtract)....
// Virtual base class defining the functor interface
class Base : public binary_function<double, double, double>
{
public:
virtual double operator()(const double& _Left, const double& _Right)
const = 0;
};
// An adder class
class Add : public Base
{
public:
double operator()(const double& _Left, const double& _Right) const
{
return _Left + _Right;
}
};
// A multiplier class
class Subtract : public Base
{
public:
double operator()(const double& _Left, const double& _Right) const
{
return _Left - _Right;
}
};
.... in my code I now want to construct the relevant accumulator
function (held as a smart pointer, e.g. boost::shared_ptr) and then
call run the accumulator:
void main
{
vector<double> a(100, 1.0); // build a vector of 1's
vector<double>::iterator p1 = a.begin();
vector<double>::iterator p2 = a.end();
// ... obtain user choice ....
// create accumulator based on user choice
boost::shared_ptr<Base> Accumulator;
switch (userChoice)
{
case ADD:
Accumulator = boost::shared_ptr<Base>(new Subtract);
break;
case SUBTRACT:
Accumulator = boost::shared_ptr<Base>(new Subtract);
break;
}
// accumulate
double result = accumulate(p1, p2, 0.0, Accumulator());
}
Obviously, this won't work, but does anyone out there know of a way of
achieving my aim? To summarise, how can I get accumulate to work with
(a) polymorphic classes, and (b) through a shared_ptr?
I would ditch the shared_ptr and inheritance business. The tr1::function
template demonstrates a method for combining runtime polymorphism with
value semantics and independent of inheritance:
#include <vector>
#include <tr1/functional>
#include <numeric>
typedef double bin ( double, double );
typedef std::tr1::function<bin> acc_type;
int main ( void ) {
std::vector<double> a(100, 1.0); // build a vector of 1's
std::vector<double>::iterator p1 = a.begin();
std::vector<double>::iterator p2 = a.end();
// ... obtain user choice ....
// create accumulator based on user choice
int userChoice = 1;
acc_type Accumulator;
switch (userChoice)
{
case 0:
Accumulator = std::plus<double>();
break;
case 1:
Accumulator = std::minus<double>();
break;
}
// accumulate
double result = accumulate(p1, p2, 0.0, Accumulator);
}
Best
Kai-Uwe Bux
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]