cpp-ru / ideas

Идеи по улучшению языка C++ для обсуждения
https://cpp-ru.github.io/proposals
Creative Commons Zero v1.0 Universal
89 stars 0 forks source link

vector::truncate #376

Open apolukhin opened 3 years ago

apolukhin commented 3 years ago

Перенос предложения: голоса +9, -0 Автор идеи: Андрей Руссков

Методы erase/resize могут не подходить для некоторых типов

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 нагляднее передает намерения программиста.

apolukhin commented 3 years ago

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

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

apolukhin commented 3 years ago

Нужно больше мотивации и примеров, где это может быть полезным