将一系列struct vector插入struct成员类型的向量中

时间:2014-11-17 09:22:48

标签: boost vector struct c++03

是否可以将struct的范围直接插入到相同类型的向量中(相同类型的struct成员)。

让我们有一个结构和这样的向量:

struct pnt {
  char _name;
  int _type;
  bool _aux;
  };

std::vector<pnt> pnts;
std::vector<int> pntType;

问题是如何使用C ++ 98的单一标准行将一系列 pnts 插入 pntType

void insert (iterator position, InputIterator first, InputIterator last);

甚至是Boost库。 由于我经常在我的代码的不同部分使用它,我试图避免在循环中执行此操作。最后一个选项是定义一个函数。

修改

我知道插入语法。我不能做的是如何从 pnts (仅每个成员的_type)插入 pntType

3 个答案:

答案 0 :(得分:4)

更新:有一个比我的第一个建议更好的方法(见下),因为我们已经在使用Boost了。 std :: transform和std :: insert_iterator的问题是v2被调整了几次,考虑到我们事先知道了范围的宽度,这是浪费的。使用boost :: transform_iterator和boost :: bind,可以避免这样的问题:

#include <boost/bind.hpp>
#include <boost/iterator/transform_iterator.hpp>

#include <algorithm>
#include <iostream>
#include <iterator>
#include <vector>

struct A {
  int x;
};

int main() {
  A arr[] = {
    { 0 }, { 1 }, { 2 }, { 3 }, { 4 }, { 5 }, { 6 }
  };

  std::vector<A> v1(arr, arr + 6);
  std::vector<int> v2;

  v2.insert(v2.begin(),
            boost::make_transform_iterator(v1.begin() + 2, boost::bind(&A::x, _1)),
            boost::make_transform_iterator(v1.begin() + 4, boost::bind(&A::x, _1)));

  std::copy(v2.begin(), v2.end(), std::ostream_iterator<int>(std::cout, "\n"));
}
老人建议:

boost :: bind适用于数据成员指针,因此使用C ++ 98和Boost,您可以在不更改结构的情况下执行此类操作:

#include <boost/bind.hpp>

#include <algorithm>
#include <iostream>
#include <iterator>
#include <vector>

struct A {
  int x;
};

int main() {
  A arr[] = {
    { 0 }, { 1 }, { 2 }, { 3 }, { 4 }, { 5 }, { 6 }
  };

  std::vector<A> v1(arr, arr + 6);
  std::vector<int> v2;

  // one-liner here:
  std::transform(v1.begin() + 2,
                 v1.begin() + 4,
                 std::insert_iterator<std::vector<int> >(v2, v2.begin()),
                 boost::bind(&A::x, _1));

  std::copy(v2.begin(), v2.end(), std::ostream_iterator<int>(std::cout, "\n"));
}

答案 1 :(得分:2)

使用提升范围:

boost::copy(pnts | transformed(std::mem_fn(&pnt::_type)), std::back_inserter(pntType));

甚至

boost::copy_range<std::vector<int>>(pnts | transformed(std::mem_fn(&pnt::_type)));

查看 Live on Coliru

请注意,您可以使用boost::bind(&pnt:_type,_1)代替mem_fn来允许编译器版本

已更新要显示特定的第一个/最后一个迭代器,并在c ++ 03模式下进行编译:

<强> Live On Coliru

#include <boost/range/algorithm.hpp>
#include <boost/range/adaptors.hpp>
#include <boost/range/iterator_range.hpp>
#include <boost/bind.hpp>

using namespace boost::adaptors;
using namespace boost;

struct pnt {
    char _name;
    int _type;
    bool _aux;
};

int main() {

    std::vector<pnt> pnts(6);
    std::vector<int> pntType;

    boost::copy(
            make_iterator_range(pnts.begin(), pnts.begin()+3) | transformed(bind(&pnt::_type, _1)), 
            std::back_inserter(pntType));
}

答案 2 :(得分:0)

将一个容器插入另一个容器中,如下所示:

pntType.insert(pntType.begin(),pnts.begin(),pnts.end());

为了能够插入正确的类型,您应该将转换运算符添加到结构中int

struct pnt {
  char _name;
  int _type;
  bool _aux;

  operator int (){
    return _type;
  }     
};