2013-07-23 2 views
3
vector<int> v1, v2; 

/*1*/  vector<int> &someReference=v1;  //compiles 
/*2*/  someReference=v2;   //compiles 

vector<unique_ptr<int>> vec1, vec2; 

/*3*/  vector<unique_ptr<int>> &otherReference=vec1; //compiles 
/*4*/  otherReference=vec2;  //ERROR 

Я бы понял, если ни одна строка 3, ни 4 не скомпилировались, но третий не вызывает ошибок компиляции - по-видимому, нет проблем с инициализацией ссылки в первый раз и ее передачей; проблема возникает, когда я пытаюсь назначить ее во второй раз.Почему обращение к unique_ptr ведет себя так?

Я не могу понять, что происходит за кулисами, что делает невозможным второе назначение.

+1

google «семантика перемещения» –

ответ

6

Это не имеет никакого отношения к ссылкам, это unique_ptr, которые невозможно скопировать.

unique_ptr<int> p1, p2; 
p1 = p2; // error 

Следовательно, векторы unique_ptr не могут быть скопированы либо.

vector<unique_ptr<int>> vec1, vec2; 
vec1 = vec2; // error 
+0

Вы правы, это была глупая ошибка. Я предполагаю, что это означает, что изменить ссылку нельзя, слишком плохо. – Adrian17

+2

@ Adrian17 Правильно, ссылка является псевдонимом чего-то еще, и она всегда связана с чем-то. Вы не можете изменить то, что он псевдонимы. – juanchopanza

+0

@ Adrian17 'T &' можно рассматривать как 'T * const' (примечание: указатель' const', что мы указываем не на то), который переопределяет 'operator =' для разыменования и назначения (и аналогично для других операторов, от '.' до '+') и переопределяет конструктор для приема-адреса и хранения. Это не идеальная модель, но, тем не менее, она полезна. Или, если хотите, мы могли бы поговорить о семантике pointer-vs-reference-vs-value на copy/construct/move/move-construct. – Yakk

4

Проблема заключается в том, что вы назначаете vec1 в vec2, и это невозможно, потому что содержимое векторов не может быть назначено.

Этот

otherReference=vec2; 

точно так же, как

vec1 = vec2; 

потому что otherReference является псевдонимом для vec1. Везде, где вы видите otherReference, вы можете заменить его на vec1.

0

Инициирование ссылка является очень отличается от присвоения к нему. Когда вы инициализируете ссылку, вы устанавливаете ее для обращения к объекту. Всюду после этого использование ссылки фактически означает использование упомянутого объекта. Это означает, что присвоение «ссылке» фактически означает присвоение упомянутому объекту.

И в вашем случае назначение незаконно, потому что std::unique_ptr не может быть скопирован (так что, по расширению, ни один из них не может быть их векторным).

Смежные вопросы