c++ - 我可以在 vector 上创建 View 吗?

标签 c++ c++11 vector

我有一个函数需要对给定的元素进行排序。不得更改原始 vector ,因此我需要该 vector 的浅表拷贝。 因为我不需要自己复制元素,因为它们只被读取,所以我决定制作一个指针 vector 。 目前我有一个简单的循环填充 vector ,但我想知道是否存在甚至可能更快的内置/标准解决方案。

void calcFindMinLeftAndSort(std::vector<Location>& locationsComplete, std::vector<Location*>& locationsSorted) {
    // ...

    // copy data in new array, to keep the original untouched
    locationsSorted.reserve(locationsComplete.size());
    // looking for locationsSorted.assign(&elements)
    // yes, I could use for each instead
    for (size_t i = 0; i < locationsComplete.size(); i++)
        locationsSorted.emplace_back(&locationsComplete[i]);

    // sort 
    std::sort(locationsSorted.begin(), locationsSorted.end(), compare);
}

附加信息: locationsComplete vector 按特定顺序排序,不得更改。该 vector 在应用程序运行期间永远不会更改。 已排序的 locationsSorted vector 被另一个函数使用一次(本可以在同一函数中使用,但那样看起来更清楚)。在 next 函数的结果返回后,locationsSorted vector 被淘汰。因此,它可以被视为一种非常短暂的临时载体。

最佳答案

您可以做的,并且可能想做的,根本不是使用指针——只需将索引集排序到 locationsCompare 中即可。 ,用比较函数查找原始区域中的值。使用 C++11 非常简单:

template <typename T>
std::vector<size_t> get_sorted_positions(const std::vector<T> &v)
{
  std::vector<size_t> indices(v.size());

  std::iota(indices.begin(), indices.end(), 0); // indices now holds 0 ... v.size()-1
  std::sort(indices.begin(), indices.end(),
       [&v](size_t i_1, size_t i_2) { return v[i_1] < v[i_2]; }
  );

  return indices;
}

注意事项:

  • 唯一发生变化的数据是索引
  • 不用担心返回一个长 vector ;由于称为 NRVO 的优化,编译器将使用移动构造函数.
  • 此代码大部分来自 this answer , 但这种方法基本上是民间传说。
  • 你可能还想抽象掉你的输入是一个 vector 的事实,并只引用一个任意容器(并返回 std::vector<typename Container::size_type> );或采用一对迭代器;或者在 C++20 中——取任何范围。不过,索引仍然是一个 vector 。

关于c++ - 我可以在 vector 上创建 View 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57875915/

相关文章:

actionscript-3 - 如何声明一个填充的向量?

c++ - 运算符+重载问题

c++ - 在派生类中绑定(bind)非静态模板化成员函数

c++ - C++11 中的无锁缓存实现

linux - recvfrom() 在接收到 udp 数据包时解除阻塞,但返回 0 作为读取字节的大小(使用 oscpack)

c++ - 使用std::vector创建自定义复数类的vector

c++ - 从 vector 范围中删除特定元素

c++ - 交换 vector 以释放它

c++ - Gabor 过滤器 c++(OpenCv) :error

c++ - 格式化输出运算符标准 iostream 对象可以抛出什么样的异常?