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! ]