我可以在矢量上创建视图吗?

Can I create a view on a vector?

本文关键字:视图 创建 我可以      更新时间:2023-10-16

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

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

附加信息: 位置完整向量按特定顺序排序,不得更改。该向量在应用运行时永远不会更改。 排序的位置排序向量被另一个函数使用一次(本可以在同一函数中使用,但这样似乎更清晰(。返回下一个函数的结果后,位置排序向量将被停用。因此,它可以被视为一个非常短暂的临时载体。

您可以做的,并且可能想要做的,根本不使用指针 - 只需将索引集排序为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;
}

笔记:

  • 唯一被变异的数据是索引
  • 不要担心返回长向量;编译器将使用移动构造函数,因为优化称为NRVO。
  • 这段代码大多是从这个答案中解脱出来的,但方法基本上是民间传说。
  • 您可能还想抽象出输入是向量的事实,只需引用任意容器(并返回std::vector<typename Container::size_type>(;或者获取一对迭代器;或者在 C++20 中 - 获取任何范围。不过,索引仍然是一个向量。

不得更改原始向量。

考虑通过生成指向 const 的非 due 指针向量来强制实施此约束

template <class Container>
auto make_vector_of_const_pointers(Container& c)
{
std::vector<typename Container::const_pointer> result;
result.reserve(c.size());
std::generate_n(std::back_inserter(result), c.size(),
[it = c.cbegin()]() mutable { return &(*(it++)); });
return result;
}

例如,请参阅此处与非常量版本相比的用法示例。