如何连接多个std::vectors?

How to concatenate many std::vectors?

已经有一个关于如何连接两个向量的问题:Concatenating two std::vectors。但是,我发现开始一个新问题是合适的,因为我的问题更具体一些....

我有两个 类 看起来像这样:

class AClass {
public:
    std::vector<double> getCoeffs() {return coeffs;}
private:
    std::vector<double> coeffs;
};

class BClass {
public:
    std::vector<double> getCoeffs() {return ...;}
private:
    std::vector<AClass> aVector;
};

连接 aVector 中每个元素的系数的最佳方法是什么(即避免不必要的复制等)?

我的第一次尝试是

std::vector<double> BClass::getCoeffs(){
    std::vector<double> coeffs;
    std::vector<double> fcoefs;
    for (int i=0;i<aVector.size();i++){
        fcoefs = aVector[i].getCoeffs();
        for (int j=0;j<fcoefs.size();j++{
            coeffs.push_back(fcoefs[j]);
        }        
    }
    return coeffs;
}

我已经知道如何避免内部 for 循环(多亏了上面提到的 post),但我很确定,在一些标准算法的帮助下,这可以在一行中完成.

我目前无法使用 C++11。尽管如此,我也对如何在 C++11 中做到这一点感兴趣(如果比 "no C++11" 有任何优势)。

编辑:我会试着稍微改一下问题,让它更清楚。 连接两个向量可以通过插入来完成。对于我的例子,我会使用这个:

std::vector<double> BClass::getCoeffs(){
    std::vector<double> coeffs;
    std::vector<double> fcoefs;
    for (int i=0;i<aVector.size();i++){
        fcoefs = aVector[i].getCoeffs();
        coeffs.insert(coeffs.end(),fcoefs.begin(),fcoefs.end());        
    }
    return coeffs;
}

是否可以避免for循环? 我可以想象可以写出类似

的东西
for_each(aVector.begin(),aVector.end(),coeffs.insert(coeffs.end(),....);

您可以在 C++11 中执行此操作:

std::for_each(aVector.begin(), aVector.end(), [&](AClass i){const auto& temp = i.getCoeffs(); coeffs.insert(coeffs.end(), temp.begin(), temp.end());});

C++03 更难,因为它缺少 lambda 和 bind.

你能做的就是在你的内部循环中使用复制:

for(std::vector<AClass>::iterator it = aVector.begin(); it != aVector.end(); ++it){
     const std::vector<double>& temp = it->getCoeffs();
     coeffs.insert(coeffs.end(), temp.begin(), temp.end());
}

它们本质上是同一件事,尽管您可以通过从 getCoeffs.

返回 const std::vector<double>& 来改进两者的运行时间

编辑:

Arg,刚刚看到您在问题中添加了 insert。我以为我真的会在那里帮助你。作为一个安慰提示,您在这里真正要问的是压平 std::vectorsstd::vector。有答案here. But should you have access to boost you should look at: http://www.boost.org/doc/libs/1_57_0/libs/multi_array/doc/reference.html#synopsis

第一步是避免额外分配。如果您知道您不会增加 return 值,您可以预留到恰好合适的大小。

std::vector<double> BClass::getCoeffs(){
  typedef std::vector<double> dvec;
  dvec coeffs;
  typedef std::vector<AClass> avec;
  typedef std::vector<dvec> ddvec;
  ddvec swap_space;
  swap_space.reserve(aVector.size());
  size_t capacity = 0;
  for (avec::const_iterator it = aVector.begin(); it != aVector.end(); ++it) {
    dvec v = it->getCoeffs(); // RVO elision!
    capacity += v.size();
    swap_space.push_back();
    v.swap(swap_space.back());
  }
  dvec retval;
  retval.reserve(capacity);
  for (ddvec::iterator it = swap_space.begin(); it != swap_space.end(); ++it) {
    retval.insert( retval.end(), it->begin(), it->end() );
  }
  return retval; // NRVO
}

这应该避免对每个 AClass 进行多次分配(由它们的 API 强制执行!您应该有一个 vector<?> const& 访问器),加上 return 值的一次分配。

建议修复 AClass