Зачем нам нужна пара вставка (value_type

#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, просто неправильно (для чего и нужны понижающие голоса).