Правильно ли я считаю, что этот невинно выглядящий код довольно опасен?
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()));
}
Это также кажется мне опасным, потому что vector.back () возвращает ссылку, и
вставки в позиции, отличные от конца вектора, выполняются путем перемещения всех элементов между позицией и концом вектора в их новые позиции, а затем вставляются новые элементы
(от Вот)
Если я не понял, ссылка передана insert
становится «недействительным» (если перераспределение не происходит, он может содержать не последний элемент, а предыдущий; в противном случае он все еще может быть правильным, но я думаю, что это не гарантировано.
Возможно, что в некоторых случаях некоторые оптимизаторы могут скрывать ошибку (я думаю, что это никогда не происходит с объектами, но может случаться с примитивами), поэтому вы получите ожидаемые результаты, но в целом я бы не стал полагаться на такое поведение.
Предполагая, что вы обратились к двум пунктам, упомянутым в комментариях, чтобы сделать эту компиляцию, это будет выполняться, но будет оставлять значение мусора в начале вектора каждый раз, когда он выполняется, из-за того, что vector.back () возвращает ссылка.
Похоже, это пытается сделать следующее:
template<typename T>
void insertLast(std::vector<T>& v)
{
if(v.empty()) return;
v.insert(v.begin(), v.end() - 1, v.end());
}
Это безопасно вставит последний элемент в вектор, так что это также первый элемент …. Предполагая, что это желаемое поведение.