7

我有一些私有类成员,代表std::deque包含一些数据的随机访问数组:

std::vector<std::deque<SomeDataClass> > someMember;

我想提供一个公共类方法,它返回可迭代的数据结构,包含我的双端队列数组中的所有数据元素:

std::deque<SomeDataClass> someMethod();

我希望这个方法遍历向量中的所有双端队列,并将其路径上的每个元素复制到本地 std::deque,最终按值返回这个本地 std::deque。我正在尝试使用 C++11autostd::begin(),来实现此方法std::end()

std::deque<SomeDataClass> MyClassName::someMethod(){
    std::deque<DirectedEdge> allDataItems;
    std::deque<DirectedEdge>::iterator deqIter = allDataItems.begin();
    for(auto it = std::begin(someMember); it != std::end(someMember); ++it){
        std::copy(std::begin(*it), std::end(*it), deqIter);
    }

    return allDataItems;
}

我在双端队列标头中的运行时收到数据访问冲突未处理的异常错误。什么是错误?

4

2 回答 2

13

std::copy()要求目标范围足够大以容纳副本,但allDataItems为空。您必须allDataItems提前预订空间(但这是不可能的std::deque)。您应该使用std::back_inserter(defined in <iterator>) 代替:

std::deque<SomeDataClass> MyClassName::someMethod(){
    std::deque<DirectedEdge> allDataItems;
    for(auto it = std::begin(someMember); it < std::end(someMember); ++it){
        std::copy(std::begin(*it), std::end(*it), std::back_inserter(allDataItems));
    }

    return allDataItems;
}
于 2013-07-16T07:42:53.717 回答
4

这是一种惯用的 C+11 方法:

std::deque<SomeDataClass> MyClassName::someMethod() {
  std::deque<DirectedEdge> allDataItems;

  for( auto const& dq : someMember ) {
    allDataItems.insert( allDataItems.end(), std::begin(dq), std::end(dq) );
  }
  return allDataItems;
}

另一种方法是编写一个concatinate函数:

struct concatenate {
  template<typename Dest, typename Src>
  Dest&& operator()( Dest&& d, Src const& s ) const {
    using std::begin; using std::end;
    typename std::decay<Dest>::type retval = std::forward<Dest>(d);
    retval.insert( end(retval), begin(s), end(s) );
    return std::move(retval);
  }
};
std::deque<SomeDataClass> MyClassName::someMethod() {
  using std::begin; using std::end; // enable ADL
  return std::accumulate(
    begin(someMember), end(someMember),
    std::deque<DirectedEdge>(), concatenate()
  );
}

这很可爱。如果你不喜欢std::accumulate

std::deque<SomeDataClass> MyClassName::someMethod() {
  std::deque<DirectedEdge> allDataItems;

  for( auto const& dq : someMember ) {
    allDataItems = concatenate( std::move(allDataItems), dq );
  }
  return allDataItems;
}

两者的效率大致相当。

于 2013-07-16T21:59:33.223 回答