c ++ 11 — побочный эффект c ++ векторное копирование и удаление

У меня есть эта проблема:

void foo(vector<int> &a){
vector<int> b;
b.push_back(1); // in general many push backs
a = b;
}

поскольку b является локальной переменной, она будет удалена, когда foo закончится.
Сохранят ли значения, вставленные в b?
Я пытался, и это делает, но, возможно, это только случайно.

Спасибо за помощь.

РЕДАКТИРОВАТЬ:

Я думаю, что это отвечает на мой вопрос. Не так ли?
http://www.cplusplus.com/reference/vector/vector/operator=/
Таким образом, в основном, a сохранит значения в c ++ 98. Но я не могу полностью понять, что он делает в C ++ 11.

2

Решение

a = b вызовет оператор копирования из std::vector, Этот оператор копирует все содержимое вектора из b в a так b может быть безопасно удален впоследствии.

Учитывая ваше редактирование:
Этот ответ также верен для C ++ 11. C ++ 11 только добавляет оператор присваивания перемещения, но этот оператор не вызывается, так как b не является r-значением.

Даже если b было значение r (например, путем оборачивания b в std::move(b)), тогда будет вызван оператор присваивания перемещения, что также будет хорошо. Было бы переместить содержимое b в a, так b впоследствии будет пустым вектором, который также можно безопасно удалить.

6

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

В C ++ 11 происходит то, что оператор присваивания будет делать копию, если вы явно не скажете ему перемещаться с использованием std :: move.

Чтобы форсировать движение, вы можете сделать это:

void foo(vector<int> &a){
vector<int> b;
b.push_back(1); // in general many push backs
a = std::move(b);
}

Чтобы это работало, вектор реализовал оператор присваивания для перемещения что-то вроде этого:

vector<T>& vector<T>::operator =(vector<T>&& to_move) {}

Когда используешь std::move, это говорит компилятору использовать перегруженную функцию, которая реализовала перемещение, в противном случае она вернется к const vector<T>& в старых версиях, в которых не реализована семантика перемещения.

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

например

vector<T>& vector<T>::operator =(vector<T>&& to_move)
{
delete [] m_ptrs;
m_ptrs = to_move.m_ptrs;
m_size = to_move.m_size;
to_move.m_ptrs = nullptr;
to_move.m_size = 0;
return *this;
}

Это, конечно, обоснованное предположение, но, надеюсь, оно демонстрирует, что может произойти при использовании семантики перемещения.

2

Если эти значения не являются указателями, они будут скопированный в a = b поэтому они будут сохранены (они также будут предварительно скопированы в b когда они вставлены http://www.cplusplus.com/reference/vector/vector/push_back/).

Если они есть, они тоже будут скопированы, но если они указывали на локальные переменные, вы получите хорошую коллекцию недопустимых указателей.

С другой стороны, если бы они были указателями на динамически распределенную память, то вы не нашли бы никаких проблем.

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