вставка в вектор

Правильно ли я считаю, что этот невинно выглядящий код довольно опасен?

template<typename T>
void insertLast(std::vector<T>& v)
{
if(v.empty()) return;
v.insert(v.begin(), v.back());
}

некоторые разъяснения после прочтения некоторых ответов ..

ну, я на самом деле не спрашиваю, как вставить элемент в вектор, но я поставил фиктивную ситуацию, чтобы поставить под сомнение принцип. Другими словами, считаете ли вы, что необходимо сделать копию (здесь создается временный объект … и const ссылка на временную гарантированно живёт):

template<typename T>
void insertLast(std::vector<T>& v)
{
if(v.empty()) return;
v.insert(v.begin(), T(v.back()));
}

4

Решение

Это также кажется мне опасным, потому что vector.back () возвращает ссылку, и

вставки в позиции, отличные от конца вектора, выполняются путем перемещения всех элементов между позицией и концом вектора в их новые позиции, а затем вставляются новые элементы
(от Вот)

Если я не понял, ссылка передана insert становится «недействительным» (если перераспределение не происходит, он может содержать не последний элемент, а предыдущий; в противном случае он все еще может быть правильным, но я думаю, что это не гарантировано.

Возможно, что в некоторых случаях некоторые оптимизаторы могут скрывать ошибку (я думаю, что это никогда не происходит с объектами, но может случаться с примитивами), поэтому вы получите ожидаемые результаты, но в целом я бы не стал полагаться на такое поведение.

2

Другие решения

Предполагая, что вы обратились к двум пунктам, упомянутым в комментариях, чтобы сделать эту компиляцию, это будет выполняться, но будет оставлять значение мусора в начале вектора каждый раз, когда он выполняется, из-за того, что vector.back () возвращает ссылка.

Похоже, это пытается сделать следующее:

template<typename T>
void insertLast(std::vector<T>& v)
{
if(v.empty()) return;
v.insert(v.begin(), v.end() - 1, v.end());
}

Это безопасно вставит последний элемент в вектор, так что это также первый элемент …. Предполагая, что это желаемое поведение.

1

По вопросам рекламы [email protected]