#c #c 11 #rvalue-reference
Вопрос:
Привет, я пытаюсь понять, как использовать перегруженные версии функции со ссылками rvalue и lvalue в качестве параметров. Итак, это пример, который я пишу, чтобы лучше понять разницу:
автомобиль.ч
class Car{
private:
int number=1000;
string name="default name";
std::set<int> Carset;
public:
void pushtoset(int amp;);
void pushtoset(int amp;amp;);
}
car.cpp
#include "car.h"
void Car::pushtocar(int amp;x){
Carset.insert(x);
}
void Car::pushtocar(int amp;amp;x){
Carset.insert(x);
}
main.cpp
int main(){
Car object;
int x = 43;
object.pushtocar(x); //this calls pushtocar(intamp;) version(say version I)
object.pushtocar(54); // this calls pushtocar(int amp;amp;) version(say version II)
return 0;
Мой вопрос в случае версии II, когда тело этой функции-члена завершено, и поскольку внутри тела функции параметр x является значением lvalue(которое является локальным для функции), x будет уничтожен. Означает ли это, что значение, которое мы вставили в набор, также будет уничтожено? Если да, то как я могу предотвратить уничтожение значения, которое помещается в набор? Мой второй вопрос, который, я думаю, связан с первым, заключается в том, что когда я пишу Carset.insert(x);
в версии II будет ли x скопирован или перемещен? Я думаю, что это будет скопировано. И поэтому, если x скопирован, то нет никаких проблем, если x будет уничтожен, потому что вставленный элемент и x независимы друг от друга. Но теперь вместо этого, если я напишу Carset.insert(std::move(x));
тогда x будет «перемещен» в набор, а не скопирован. Таким образом, в этом случае у нас возникнет проблема: после завершения тела функции x будет уничтожен, и поэтому вставленный элемент также будет уничтожен. Есть ли какой-либо способ предотвратить уничтожение элемента, вставленного в набор в этом перемещенном случае, который оставляет x в допустимом состоянии? Также верно ли мое понимание концепции?
Комментарии:
1. Перемещение
int
-это просто копия… использованиеstd::string
вместоint
этого сделает пример более значимым.2. » x будет уничтожен, и поэтому вставленный элемент также будет уничтожен». Это не то, как работает перемещение.
Ответ №1:
Версия II принимает «swap» [std::move], поэтому после завершения параметр, переданный функции, не определен. вы больше не можете им пользоваться. ссылка на значение rvalue продлевает срок службы объекта, он не будет уничтожен немедленно. Версия, которую я использую, имеет значение lvalue, поэтому это конструктор копирования. Правильная форма для этого должна быть
void Car::pushtocar(const int amp;x){
Carset.insert(x);
}
Комментарии:
1. Но .insert() может принимать как значение lvalue, так и ссылочные параметры rvalue. Когда я называю это так
Carset.insert(std::move(x));
, тогда следует использовать справочную версию rvalue. То есть значение должно быть перемещено, а не скопировано. cplusplus.com/reference/set/set/insert и когда x выйдет за пределы видимости, он будет уничтожен. Но мы вставили(переместили) значение в набор. Будет ли он уничтожен и оттуда тоже?2. Доступ к x-это неопределенное поведение, поскольку оно было заменено значением, сгенерированным внутри контейнера. Мы не знаем, какое значение примет x
3. Не знаю, как это оказалось в очереди VLQ. Это не VLQ, просто неправильно (для чего и нужны понижающие голоса).