Search code examples
c++boostbindingboost-bindboost-iterators

How to copy with member access using boost


I have a container of As with

struct A { int f(); }

The container offers iterators and we can for this example assume it's an std::vector. So:

std::vector<A> As;

Now I want to copy the values provided by A::f into a second container

std::vector<int> fs;

Although I could simply iterate, as an exercide I tried to solve this with boost bind / boost iterator. What I tried so far is this:

std::copy(
     boost::make_transform_iterator
         (As.begin(), boost::bind(&A::f, _1)),
     boost::make_transform_iterator
         (As.begin(), boost::bind(&A::f, _1)),
     std::back_inserter( fs )
);

Anyone know how this can be done?


Solution

  • If I change the second make_transform iterator to point to end() instead of begin(), everything appears to work.

    #include <boost/iterator/transform_iterator.hpp>
    #include <boost/bind.hpp>
    #include <iostream>
    #include <vector>
    
    struct A {
        int f() {
            static int x = 0;
            return x++;
        };
    };
    
    int main() {
        std::vector<A> As;
        As.push_back(A());
        As.push_back(A());
        As.push_back(A());
    
        std::vector<int> fs;
    
        std::copy(
                boost::make_transform_iterator(As.begin(), boost::bind(&A::f, _1)),
                boost::make_transform_iterator(As.end(),   boost::bind(&A::f, _1)),
                std::back_inserter(fs)
                );
    
        for (int const & x : fs)
            std::cout << x << std::endl;
    }
    

    Output

    0
    1
    2
    

    Alternative Solutions

    You could also solve this with a functor:

    struct Functor {
        int operator()(A & value) const {
            return value.f();
        }
    };
    
    std::transform(As.begin(), As.end(), std::back_inserter(fs), Functor());
    

    or with a lambda:

    std::transform(As.begin(), As.end(), std::back_inserter(fs), [](A & a) { return a.f(); });