vector::truncate

Андрей Руссков
Андрей Руссков

vector::resize требует чтобы тип значения был MoveInsertable и DefaultInsertable или CopyInsertable для разных перегрузок. vector::erase требует MoveAssignable. Таким образом, возможны типы, для которых ни один из вариантов не подходит. Минимальный пример:

#include <vector>
#include <string>

using namespace std;

struct S {
    S(string s) : s(s) {}
    S(S&&) = delete;
    
    string s;
};

int main() {
    vector<S> v;
    v.emplace_back("abc");
    v.emplace_back("def");
    v.emplace_back("ghi");

    v.erase(prev(v.end())); // error: S is not MoveAssignable
    v.resize(v.size() - 1); // error: S is not DefaultInsertable and MoveInsertable
}

 

Предлагаю ввести метод vector::truncate(size_t n), который удаляет лишние элементы с конца вектора если n < size(), и ничего не делает в противном случае. Такой метод будет требовать от типа только Eraseable. Помимо прочего, метод truncate нагляднее передает намерения программиста.

3
рейтинг
2 комментария
yndx-antoshkka

Идея супер. Но есть ещё проблема с emplace_back - он требует чтобы тип данных был MoveConstructible, из-за чего вышеприведённый пример не собирается: https://godbolt.org/z/ITQ6Eh

yndx-antoshkka
Обновлено 
Андрей Руссков

yndx-antoshkka, да, мой косяк. Засунуть в вектор не-MoveInsertable элемент в вектор видимо не получится. Но в любом случае в векторе может быть тип, для которого не подходит один из вариантов resize/erase, а ограничения для них более серьезные, чем нужны для truncate, поэтому актуальность он не потеряет

Андрей Руссков
Другие идеи
Группа создана, чтобы собирать предложения к стандарту C++, организовывать их внутренние обсуждения, помогать готовить их для отправки в комитет и защищать на общих собраниях в рабочей группе по С++ Международной организации по стандартизации (ISO).
Все предложения