У меня есть эта проблема:
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.
a = b
вызовет оператор копирования из std::vector
, Этот оператор копирует все содержимое вектора из b
в a
так b
может быть безопасно удален впоследствии.
Учитывая ваше редактирование:
Этот ответ также верен для C ++ 11. C ++ 11 только добавляет оператор присваивания перемещения, но этот оператор не вызывается, так как b
не является r-значением.
Даже если b
было значение r (например, путем оборачивания b в std::move(b)
), тогда будет вызван оператор присваивания перемещения, что также будет хорошо. Было бы переместить содержимое b
в a
, так b
впоследствии будет пустым вектором, который также можно безопасно удалить.
В 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;
}
Это, конечно, обоснованное предположение, но, надеюсь, оно демонстрирует, что может произойти при использовании семантики перемещения.
Если эти значения не являются указателями, они будут скопированный в a = b
поэтому они будут сохранены (они также будут предварительно скопированы в b
когда они вставлены http://www.cplusplus.com/reference/vector/vector/push_back/).
Если они есть, они тоже будут скопированы, но если они указывали на локальные переменные, вы получите хорошую коллекцию недопустимых указателей.
С другой стороны, если бы они были указателями на динамически распределенную память, то вы не нашли бы никаких проблем.