2013-08-24 22 views
6

Piszę implementację standardowej biblioteki C++ do nauki.Powracanie std :: move (f) w std :: for_each

Standard C++ 11 mówi, że for_each zwraca std::move(f).

template <class InputIterator, class Function> 
Function for_each(InputIterator first, InputIterator last, Function f); 

Returns: std::move(f). 

Myślałem, że zmienna lokalna zakresu funkcji jest skonstruowana w ruchu po jej zwróceniu. Czy muszę jawnie zwrócić move(f)?

+3

W tym przypadku zwracanie 'std :: move (f)' jest * prawie * równoważne zwracaniu 'f'. C++ 11 zabrania optymalizacji wartości zwracanej dla parametrów funkcji (ale nadal pozwala na niejawny ruch dla nich). Tak więc wydaje mi się, że jedyną różnicą jest to, że 'return f;' wraca do uznania go za lwartość, jeśli wartość rna spowodowałaby nadmierną dwuznaczność lub nie znalazłaby żadnego konstruktora. Ale "ruch powrotny (f)" w takim przypadku zawiedzie ze złym kształtowaniem. –

+1

Na przykład zachowanie będzie inne dla 'funkcji', która jest zdefiniowana jak ta' struct Funkcja {funkcja (funkcja &); }; '. Ta klasa nie ma konstruktora ruchu i konstruktora kopiowania, który nie akceptuje wartości r. Zwrot 'move (f) 'byłby zatem źle sformułowany, podczas gdy' return f; 'byłby dobrze sformułowany. –

+1

Ale znowu nie jestem pewien, jakie ograniczenia bibliotek dla obiektów funkcji są. Być może wymagają one, aby funkcja "function" była kopiowalna do inicjalizacji z rvalues. W takim razie nie byłoby żadnych różnic, o ile widzę. –

Odpowiedz

2

Od Josuttis „s C++ Standardowa biblioteka

Nie muszą i nie powinny przejść() wartości zwracanych. Zgodnie z regułami języka, norma określa, że ​​na następny kod jest gwarantowana

X foo() 
{ 
X x; 
... 

return x; 
} 

następujące zachowanie:

• Jeżeli X ma dostępną kopię lub przenieść konstruktora, kompilator może wybrać abstrahować Kopiuj. Jest to tak zwana (zwana) wartość zwracana optymalizacja ((N) RVO), która została określona nawet przed C++ 11 i jest obsługiwana przez większość kompilatorów.

• W przeciwnym razie, jeśli X ma konstruktor ruchu, przesunięto x.

• W przeciwnym razie, jeśli X ma konstruktora kopiowania, kopiowane jest x.

• W przeciwnym razie zostanie wygenerowany błąd podczas kompilacji.

Od §25.2.4 (for_each)

Wymaga: Funkcja musi spełniać wymogi MoveConstructible (tabela 20). [Uwaga: Funkcja nie musi spełniać wymagania CopyConstructible (tabela 21) .- koniec Uwaga]

Z std::move(f) można być gwarantowane jest w stanie odczytać z zewnątrz zmutowany stan.

+0

Brakowało mi wymagania "funkcji". Dzięki. – kukyakya

+1

Pytanie to jednak pyta o parametr funkcji "f", podczas gdy standard zamiast tego podaje przykład ze zmienną lokalną. Czy RVO ma zastosowanie do parametrów funkcji? – Hugues

Powiązane problemy