Как мне построить поддиапазон вектора по ссылке? - PullRequest
1 голос
/ 17 мая 2019

В настоящее время я использую конструктор диапазона 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 в качестве параметра.Я не хочу передавать итераторы, как обсуждено здесь .Предположим, что я не контролирую функцию fun.

1 Ответ

3 голосов
/ 17 мая 2019

Вектор C ++ - это тип, который «владеет» своей памятью - он не может быть «ссылочным типом» в данных другого вектора.

Вместо этого вы, вероятно, найдете span полезным: span - это класс, представляющий непрерывные данные в памяти - как вектор; но - это является «ссылочным типом», и оно не владеет - именно тем, что вы хотели иметь. Он ведет себя как вектор w.r.t. итерация, 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 из Библиотеки поддержки рекомендаций (например, здесь ).

...