2017-02-12 55 views
6

Czy ktoś może dać mi wskazówki, dlaczego ten kod nic nie wyświetla? Jestem zakładając, że ma coś wspólnego z linią ruchu ...Nieprawidłowe użycie przeniesienia?

#include <iostream> 
#include <vector> 
#include <algorithm> 

using namespace std; 

int main(){ 
vector<int> v{66,79,154,24,76,13,7}; 

v = move(v); 
for(auto i: v) 
cout << i << " "; 
} 

Update: Więc system ("pause") dodanej; aby pomóc sobie. Niezależnie od tego, czy tego potrzebuję, czy nie, nie koncentruję się na tym. Kiedy ponownie uruchomiłem kod w Visual Studio 2013, zadziałało. Jednakże, gdy przeprowadziłem go przez Ideone przy użyciu C++ 14, nic nie wynikło. Nieco zdezorientowany teraz.

Visual Studio 2013 Ideone

+0

'v = move (v);' jest niezdefiniowanym zachowaniem? –

+0

czym jest używany kompilator? –

+0

Obecnie używa programu Visual Studio. –

Odpowiedz

2

będę musiał powiedzieć, że jest unreproducible.

użyłem mojego Visual Studio 2015 Update 3 i wyjście jest normalne:

Ponadto, w ramach realizacji VC++ nie ma problemu porusza wektorowi sam:

_Myt& operator=(_Myt&& _Right) 
     { // assign by moving _Right 
     if (this != &_Right) 
      { // different, assign it 
      clear(); 

     if (_Alty::propagate_on_container_move_assignment::value 
      && this->get_allocator() != _Right.get_allocator()) 
      { // assign vector, dumping proxy 
      this->_Free_proxy(); 
      this->_Myvec = _STD move(_Right._Myvec); 
      this->_Alloc_proxy(); 
      } 
     else 
      this->_Myvec = _STD move(_Right._Myvec); 


     this->_Mysize = _Right._Mysize; 
     _Right._Mysize = 0; 
     } 
    return (*this); 
    } 

jak widać ze stanu this != &_Right, ruchoma będzie tylko wtedy, jeśli nie są przenoszeniem wektora do siebie.

EDIT:

najwyraźniej kompilator, który jest używany do kompilacji „C++ 14” na Ideone (? GCC) zdecyduje się nie sprawdzić przypisanie własny ruch i postanawia uwolnić dane wektorowe. , jak widzimy z this little experiment, po ruchu wielkość wektora wynosi 0. jak powiedziano w innych poprzednich odpowiedziach/komentarzach, przypisanie ruchu do siebie jest zdefiniowane przez implementację. Sądzę, że VC++ ma w tym przypadku słuszność.

EDIT 2:

wydaje się, że GCC naprawdę doesn't check for self asignment. przenosi dane wektorowe w tymczasowym jednej i bierze __x danych, który w tym momencie jest już pusta. człowieku, czasami GCC zachowuje się głupio tylko dla zachowania fałszywego sensu (ponieważ cmp + jz naprawdę spowolni twój program w dół?).)

+0

Właśnie przetestowałem to na Ideone, ponieważ obecnie używam mojego telefonu i zapomniałem otworzyć aplikację kompilatora, którą mam. Wypróbowałem to jeszcze raz i nie wyprodukowałem żadnego wyjścia. Czy zmieniłeś lub dodałeś coś? –

+0

po powrocie wklej sekcję z widokiem i zobacz + dokładną wersję kompilatora +. i nie, nic nie zmieniłem. –

+0

Więc na podstawie twojej najnowszej edycji, zakładam, że powinienem pójść w oparciu o to, co pokazuje mi Visual Studio? –

4

standardowych funkcji bibliotecznych zwanych z xvalue argumentów może przyjąć argumentu jest tylko odniesienie do obiektu; jeśli został zbudowany z lvalue z std::move, nie są wykonywane żadne testy aliasingu. W szczególności oznacza to, że operatory przypisania standardowy ruch biblioteka nie trzeba wykonywać kontrole samo zadanie:

std::vector<int> v = {2, 3, 3}; 
v = std::move(v); // undefined behavior 

Więcej szczegółów można znaleźć std::move i this question

+2

Kolejne istotne pytanie: http: // stackoverflow.com/q/13129031/576911 i +1. –