如何使用boost复制成员访问权限

时间:2013-03-21 18:33:08

标签: c++ boost binding boost-bind boost-iterators

我有一个As的容器

struct A { int f(); }

容器提供了迭代器,我们可以为这个例子假设它是一个std :: vector。所以:

std::vector<A> As;

现在我想将A :: f提供的值复制到第二个容器中

std::vector<int> fs;

虽然我可以简单地迭代,但作为一个练习我尝试使用boost bind / boost迭代器来解决这个问题。到目前为止我尝试的是:

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 )
);

任何人都知道如何做到这一点?

2 个答案:

答案 0 :(得分:3)

如果我将第二个make_transform迭代器更改为指向end()而不是begin(),则一切似乎都有效。

#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;
}

输出

0
1
2

替代解决方案

你也可以用仿函数来解决这个问题:

struct Functor {
    int operator()(A & value) const {
        return value.f();
    }
};

std::transform(As.begin(), As.end(), std::back_inserter(fs), Functor());

或使用lambda:

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

答案 1 :(得分:1)

您希望传递给make_transform_iterator的类似函数的对象获取A并返回在f上调用A的结果。虽然您可以像bind那样执行此操作,但您可以使用std::mem_fn更明确地执行此操作:

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

请注意,第二个转换迭代器应该适应As.end()