【问题标题】:How to copy with member access using boost如何使用 boost 复制成员访问权限
【发布时间】:2013-03-11 10:16:59
【问题描述】:

我有一个 As with 容器

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

有人知道这是怎么做到的吗?

【问题讨论】:

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


    【解决方案1】:

    您希望传递给make_transform_iterator 的类函数对象采用A 并返回对该A 调用f 的结果。虽然您可以像使用 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()

    【讨论】:

      【解决方案2】:

      如果我将第二个 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(); });
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-04-26
        • 2017-10-08
        • 2014-06-14
        • 1970-01-01
        • 2011-06-01
        • 1970-01-01
        相关资源
        最近更新 更多