c ++向量以简洁的方式推回另一个向量的切片

问题描述

我的意思是从具有相同值的线性排列的 K 大小的向量构建一个由 M 个 N 大小的向量组成的向量,即总元素为 K=M*N。 此外,我会在类构造函数中这样做,尽管我认为这无关紧要。 我的代码如下所示。

我应该在 pushback 行中使用什么?

template <int dim>
class vec2d {
  public:
    // Constructor - Version 1: 2D array as initializer
    vec2d(const std::vector<std::vector<double> >& c);
    // Constructor - Version 2: 1D array as initializer
    vec2d(const std::vector<double>& c);
    ...
  protected:
    std::vector<std::vector<double> > _vec2d;
};

// Version 1: 2D array as initializer
...

// Version 2: 1D array as initializer
template <int dim>
vec2d::vec2d(const std::vector<double>& c)
{
    for (size_t i = 0; i < (c.size() / dim); i++)
        _vec2d.push_back(std::vector<double>(c(i * dim),c((i+1) * dim - 1)));  // <- Fix this line
}

解决方法

std::vector 有一个接受迭代器范围的构造函数。使用它,您可以更改循环以使用它

template <int dim>
vec2d::vec2d(const std::vector<double>& c)
{
    auto begin = c.begin();
    auto end = begin + dim;
    for (size_t i = 0; i < (c.size() / dim); i++) {
        _vec2d.emplace_back(begin,end);
        begin += dim; // move range to next dim sized block
        end += dim;   // this could be moved into the for loops increment section
    }
}
,

关于:

template <int dim>
vec2d::vec2d(const std::vector<double>& c)
{
    for (auto i = c.begin(); i < c.end(); i+=dim )
        _vec2d.push_back({i,i+dim});
}

或与@NathanOlivier 的提示混合:

template <int dim>
vec2d::vec2d(const std::vector<double>& c)
{
    for (auto i = c.begin(); i < c.end(); i+=dim )
        _vec2d.emplace_back(i,i+dim);
}

我们可能会争论“emplace”是否比“push”+“{}”长,但它应该避免在作为 push_back() 参数传递的临时向量上调用移动运算符。

正如所指出的,根据您的示例,它假设:

  • c 大小是dim 的倍数(或等于dim*dim)
  • _vec2d 之前已被清除

作为优化,您应该在执行 _vec2d.resize(c.size()/dim) 方法的一系列调用之前添加 _vec2d.resize(dim)push_back()