【问题标题】:c++ vector pushback slice of another vector in a concise wayc++向量push_back以简洁的方式切片另一个向量
【发布时间】:2021-03-22 16:19:54
【问题描述】:

我的意思是从具有同一组值的线性排列的 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
}

【问题讨论】:

  • 我个人会颠覆这个问题。使vec2d 的存储成为一维向量,然后重载operator() 以获取两个独立以返回向量中的正确元素。这使构建变得容易,并为您提供更好的性能。使用 2d 向量,每一行都可以位于内存中的其他位置,这确实会影响其缓存效率。
  • 不知道是不是超出范围,我不喜欢嵌套两个向量。它巧妙地表示内部向量可以是任意大小。但实际上,它不能。所以我会转向一个使用 std::array 的模板类。这样,您可以强制“矩阵”平方。并且可能通过增加局部性来获得更高的性能。
  • 你必须构造你的向量,你不能仅仅将它分配为一个右值。因此,您必须使用 emplace_back 而不是 push_back
  • 如果你必须保留代码,我会在一行上创建 std::vector (这样你就可以在创建向量时发现错误)然后我会调用 v.push_back( std: :move(tmp_vec_double));
  • @NathanOliver - 我同意 100% ......但我是从一个继承代码类继承而来的。我现在无法改变这一点。我非常感谢知道我的意思是否可行,如果可行,如何实现。

标签: c++ vector slice push-back


【解决方案1】:

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
    }
}

【讨论】:

    【解决方案2】:

    怎么样:

    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 之前已被清除

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-28
      • 2020-05-16
      • 1970-01-01
      • 1970-01-01
      • 2011-06-09
      • 2016-11-16
      相关资源
      最近更新 更多