Skip to content

Conversation

@ivan0sokin
Copy link

@ivan0sokin ivan0sokin commented May 1, 2025

Ограничения на тип лежащий в нашем векторе ограничиваются is_nothrow_move_constructible_v || is_copy_constructible_v (назовём условиями C1 и M1), однако этого не всегда хватает методу insert. По-хорошему в нём должна быть добавка о том, что тип is_copy_assignable_v (условие C2) и is_move_assignable_v (условие M2) для соответствующих версий метода. Если их не будет, то вектор допускает использование такого типа (что является немного странным):

struct NonMoveAssignable {
  int x;

  NonMoveAssignable(int x)
    : x(x) {}

  NonMoveAssignable(NonMoveAssignable &&other) noexcept
    : x(other.x) {}

  NonMoveAssignable& operator=(NonMoveAssignable &&other) = delete;
};

В моём коде использование вектора с таким типом является возможным только до первого использования метода insert или erase, поскольку иначе проект не компилируется clang'ом (gcc в том числе) по причине невозможности сделатьstd::rotate, который в свою очередь использует std::swap (или аналогичный std::iter_swap). Свап требует явного выполнения условий C1 & C2 ИЛИ M1 & M2.
Мне кажется, что лучше явно прописать эти условия, чтобы избежать возможности создания таких "поломанных" векторов. К тому же в стандартном std::vector::insert оговаривается, что невыполнение условия C2 или M2 для соответствующих версий методов выливается в undefined behaviour, что мы наверное тоже хотим запретить.

@clzll
Copy link

clzll commented May 1, 2025

Технически, ни C2, ни M2 не необходимы, т.к. того же эффекта можно достичь вызовом деструктора и placement new (другое дело, что, конечно, отсутствие C2/M2, но наличие C1/M1, - нечто очень странное). Хотя, конечно, тогда требования к erase по безопасности исключений выглядят довольно странно, ибо указывают на использование std::swap (в то время как от insert требуется сильная гарантия безопасности в принципе, а не как у std::vector => ты не можешь использовать там std::swap в принципе (или это очередная ошибка в условии?))

P.S. Нет, я не практик

@dedlocc
Copy link
Member

dedlocc commented Jun 27, 2025

Похоже на правду. Оставлю открытым, чтобы ещё раз это обдумать при подготовке задания к следующему году.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants