Сжимайте вектор от N1 до N2 элементов, не вызывая конструктор по умолчанию и используя только семантику перемещения - PullRequest
0 голосов
/ 21 июня 2020

Не могли бы вы помочь мне найти эффективный способ уменьшить std::vector<T> с N1 до N2 (N2 <= N1) элементов, не требуя, чтобы T имел конструктор по умолчанию (т.е. resize() - это не вариант, потому что для этого требуется конструктор по умолчанию, потому что его также можно использовать для роста) и с использованием только семантики перемещения (без необходимости использования конструктора копирования / оператора присваивания в T)? Фактически ли операция сжимает выделенную память - необязательно (я еще не решил, какой из них лучше для моей программы).

Что я пробовал до сих пор:

template<typename T> void Filter(vector<T> &v) {
    // ... Filter the N1 items of the vector and move them to the first N2 positions
    vector<T>(move(v)).swap(v); // this is wrong
}

Ответы [ 4 ]

2 голосов
/ 21 июня 2020

erase кажется более чистым:

v.erase(v.begin() + N2, v.end());

, но вариант с resize - предоставить фиктивный объект:

auto& dummy = v[0]; // assuming non-empty, else create a new dummy object
v.resize(N2, dummy); 
2 голосов
/ 21 июня 2020

Самое простое решение - стереть элементы:

v.erase(v.begin() + N2, v.end());

При желании можно уменьшить зарезервированный размер:

v.shrink_to_fit();

Вы также можете использовать другую перегрузку std::move для создания нового вектора, содержащего подмножество элементов:

std::vector<T> filtered;
filtered.reserve(N2);
std::move(v.begin(), v.begin() + N2, 
          std::back_insert_iterator(filtered));
return filtered;
2 голосов
/ 21 июня 2020

Если вам нужно сделать это на месте, возможно, будет достаточно erase:

v.erase(v.begin() + N2, v.end());
2 голосов
/ 21 июня 2020

А что насчет этого?

void foo(std::vector<T>& vec)
{
    const std::size_t n = /* ... */;
    std::vector<T>(
        std::make_move_iterator(std::begin(vec)),
        std::make_move_iterator(std::begin(vec) + n).swap(vec);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...