Search code examples
c++boostc++03mem-fun

Must I use boost::bind to create polymorphic "transform" functionality?


I am trying to call a member function on each object in a vector, with a specified parameter, and I would like the call to be polymorphic. I believe the function vstuff shown below achieves this. But can vstuff be modified to take a vector< shared_ptr < Base> > without using boost::bind?

class Base{
            virtual double stuff(double t);
           }
//and some derived classes overriding stuff
//then in some code 
vector<double> vstuff(double t, vector<Base*> things)
{
vector<double> vals;
vals.resize(things.size());
transform(things.begin(), things.end(), vals.begin(), std::bind2nd(std::mem_fun(&Base::stuff),t));
return vals;
}

I know that shared_ptr s require mem_fn instead of mem_fun , but I have not succeeded in making mem_fn work with the bind2nd I need to pass in the parameter t, so I wonder whether or not it is feasible.. ?


Solution

  • You can use std::bind too (or lambdas):

    Live On Coliru

    #include <algorithm>
    #include <vector>
    #include <memory>
    
    struct Base {
        virtual double stuff(double) { return 0; }
    };
    
    struct Threes : Base {
        virtual double stuff(double) { return 3; }
    };
    
    struct Sevens : Base {
        virtual double stuff(double) { return 7; }
    };
    
    std::vector<double> vstuff(double t, std::vector<std::shared_ptr<Base> > things)
    {
        std::vector<double> vals;
        vals.resize(things.size());
        transform(things.begin(), things.end(), vals.begin(), std::bind(&Base::stuff, std::placeholders::_1, t));
        return vals;
    }
    
    #include <iostream>
    
    int main() {
        for (double v : vstuff(42, {
                    std::make_shared<Sevens>(),
                    std::make_shared<Sevens>(),
                    std::make_shared<Sevens>(),
                    std::make_shared<Threes>(),
                    std::make_shared<Sevens>(),
                    std::make_shared<Threes>(),
                    std::make_shared<Sevens>(),
                    std::make_shared<Sevens>(),
                    std::make_shared<Threes>(),
                    std::make_shared<Sevens>(),
                }))
        {
            std::cout << v << " ";
        }
    }
    

    Prints

    7 7 7 3 7 3 7 7 3 7