2009-03-20 13 views
6

W pliku previous question okazało się, że zwykła funkcja zwracania wartości zawsze kopiuje swój argument return do zmiennej, która jest z niego przypisana.Konstruktor kopiowania a optymalizacja wartości zwracanej

Czy jest to wymagane przez standard, czy też można zoptymalizować funkcję, konstruując zmienną "przypisano do" nawet w obrębie treści funkcji?

struct C { int i; double d; }; 

C f(int i, int d) { 
    return C(i,d); // construct _and_ copy-construct? 
} 

int main() { 
    C c = f(1, 2); 
} 

Odpowiedz

7

Standard umożliwia dowolny poziom kopii pominięcia tutaj:

  • skonstruować lokalny charakter tymczasowy, skopiuj ją do skonstruowania wartości powrotu, a kopia określić wartość powrotu do miejscowego „C”. LUB
  • skonstruować lokalny tymczasowy i skopiować-skonstruować na "c". LUB
  • konstrukt „c” z argumentami „I, D”
+0

Czy możesz podać numer sekcji od normy? –

+0

To samo, co Neil opublikował: 12.15. Czy interpretujesz to inaczej? –

7

Norma mówi, że konstruktor kopia nie mogą być używane - patrz punkt 12.8/15:

15 Ilekroć tymczasowy obiekt klasy są kopiowane przy użyciu konstruktora kopii, i tego obiektu i kopia ma numer tego samego typu bez cv, implementacja jest dozwolona do traktowania oryginału i kopii jako dwa różne sposoby odwoływania się do tego samego obiektu i nie wykonywania kopii podpod pod adresem wszystkie, nawet jeśli konstruktor klasy lub destruktor klasy mają konstrukcje po stronie , które mają efekty boczne .

I wiele więcej w podobnym tonie.

+0

12,5 w moim standardzie z 1998 roku to "Darmowy sklep", czy odwołujesz się do innych standardów? –

+0

Powinien być 12.8/15 –

-1

Jest jeden bardzo prosty i dobry sposób, aby uniknąć takich rozważań całkowicie - można rozważyć powrót do boost :: shared_ptr do utworzonego obiektu - będzie praktycznie taka sama, jeśli chodzi o użyteczność, ale twój obiekt na pewno nie będzie niepotrzebnie kopiowany - i będzie prawdą również, jeśli zwrócisz go przez kilka warstw wywołań funkcji.

+0

Nie jest dobrym rozwiązaniem dla shared_ptr std :: string lub std :: pair lub std :: vector. –

+0

Aby uniknąć kopiowania, mógłbym użyć sterty i.s.o. przechowywanie stosu. Wiem, że:)/ Ale chciałem wiedzieć, czy mogę zaufać kompilatorowi, tj. Standardowi _guarantee_ wywołującemu mój konstruktor kopii. Którego nie mogę. – xtofl

+0

ciekawy: dlaczego i tak potrzebujesz tej gwarancji xtof? –

0

Sposób nie przekazać parametru przez odniesienie i przypisać do niego wynik?

+0

, ponieważ jest brzydszy i mniej elastyczny w witrynie połączenia. powinno się to robić tylko w miejscach o krytycznym znaczeniu. –

+0

Lub gdy potrzebujesz wielu wartości zwracanych (status i wartość na przykład) – xtofl