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

时间:2019-05-17 16:37:41

标签: c++ slice stdvector reference-type

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

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

std::vector<int> subrangeVector(myVect.begin(), myVect.begin() + 2);

但是,这导致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;
}

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

1 个答案:

答案 0 :(得分:3)

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

相反,您可能会发现span有用:span是表示内存中连续数据的类-就像矢量;但是-它 是“引用类型”,并且拥有-正是您想要拥有的。它的行为就像矢量迭代operator[],依此类推。

在您的情况下,您应该写:

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

,然后按照您打算对向量使用子范围。

PS:这是C ++ 20代码,因为C ++ 17还没有跨度;如果您使用的是早期的C ++版本,请使用“准则支持库”中的gsl::span(例如,来自here的)。