如何通过引用构建向量的子范围?

pat*_*tyx 2 c++ reference-type slice stdvector

我目前正在利用范围构造函数std::vector来创建给定子范围的另一个向量。

std::vector<int> myVect { 1, 2, 3, 4 };

std::vector<int> subrangeVector(myVect.begin(), myVect.begin() + 2);
Run Code Online (Sandbox Code Playgroud)

但是,这会导致 myVect 的范围值被复制并占用额外的内存。当使用有限的内存和/或非常大的元素类型时,这是不可取的。

如何通过引用构建另一个向量的子范围?

我的目标的简化解释如下:

void fun(std::vector<int> & v) { v.at(0) = 1; }

int main()
{
    std::vector<int> myVect { 1, 2, 3, 4 };

    std::size_t upperLimit = 5;
    std::vector<int> subrangeVector = subrangeView(myVect, upperLimit);

    fun(subrangeVector);  // so myVect.at(0) == 1

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这将在std::vector用作参数的许多不同函数中实现。我不想传递这里讨论的迭代器。假设我无法控制函数fun

ein*_*ica 5

C++ 向量是一种“拥有”其内存的类型——它不能是另一个向量数据的“引用类型”。

相反,您可能会发现跨度很有用:跨度是表示内存中连续数据的类——就像向量一样;但是 - 它一种“引用类型”,它拥有 - 正是您想要的。它的行为类似于向量 wrt 迭代,operator[]等等。

在你的情况下,你会写:

std::vector<int> myVect { 1, 2, 3, 4 };
auto subrange { std::span{myVect}.subspan(0, 2); }
Run Code Online (Sandbox Code Playgroud)

然后按照您计划使用矢量的方式使用子范围。

PS:这是 C++20 代码,因为 C++17 还没有跨度;如果您使用的是较早的 C++ 版本,请使用gsl::span指南支持库(例如从这里)。

  • @JesperJuhl: 1. 你正在分叉。2. 数据仍然是引用包装器,而不是引用对象。 (2认同)
  • @JesperJuhl 至少我没有找到如何使用 `std::reference_wrapper` 来实现这一点的方法。 (2认同)