emSon Temat założony przez niniejszego użytkownika |
[C++] Po co zwracać referencje? » 2015-11-16 16:36:50 Jaki jest sens zwracania referencji? free_throws & accumulate( free_throws & target, const free_throws & source );
Wiadomo, że wtedy nie można wywoływać funkcji w funkcji accumulate( accumulate( team, three ), four );
Ale czy jest inne zastosowanie tego? Jeśli nie używam zagnieżdżonych funkcji mój prototyp równie dobrze może wyglądać tak: free_throws accumulate( free_throws & target, const free_throws & source );
|
|
Monika90 |
» 2015-11-16 17:05:18 Jaki jest sens zwracania referencji? |
Zobacz np. operator [] klasy std::vector Wiadomo, że wtedy nie można wywoływać funkcji w funkcji
accumulate( accumulate( team, three ), four );
|
Można, zobacz operator wstawiania do strumienia << - zwraca referencję, a możliwe jest wywołanie łańcuchowe (to co ty nazywasz wywołaniem funkcji w funkcji) równie dobrze może wyglądać tak:
free_throws accumulate( free_throws & target, const free_throws & source );
|
Między zwracaniem referencji, a wartości jest duża różnica. Czy w tym przypadku można zastąpić jedno drugim - nie wiem, bo nie wiem co ta funkcja ma robić. |
|
emSon Temat założony przez niniejszego użytkownika |
» 2015-11-16 17:17:17 O tym operatorze się jeszcze nie uczyłem. Funkcja ta zwraca podesłaną przez referencję strukture: free_throws & accumulate( free_throws & target, const free_throws & source ) { target.attempts += source.attempts; target.made += source.made; return target; }
Czy w tym wypadku jest jakaś różnica? |
|
Monika90 |
» 2015-11-16 17:28:07 Jeżeli będziesz zwracał przez wartość, to nie będziesz mógł wywołać tej funkcji w ten sposób accumulate( accumulate( team, three ), four );
ponieważ ta funkcja jako pierwszego argumentu wymaga L-wartości, a obiekt zwracany z funkcji przez wartość jest R-wartością. Dlatego tutaj musisz zwracać referencję. Inny powód zwracania referencji to to że prawdopodobnie chcesz uniknąć zbędnych kopii obiektu team. (ale nie zwracaj referencji do obiektów lokalnych - to byłby błąd) UWAGA, jeżeli używasz kompilatora Microsoftu, to powyższe wywołanie się skompiluję nawet jeżeli nie zwracasz przez referencję, ale takie zachowanie kompilatora nie jest zgodne ze standardem. |
|
emSon Temat założony przez niniejszego użytkownika |
» 2015-11-16 17:32:29 Ok, już rozumiem. Dzięki ci wielkie ;) |
|
j23 |
» 2015-11-16 17:44:22 UWAGA, jeżeli używasz kompilatora Microsoftu, to powyższe wywołanie się skompiluję nawet jeżeli nie zwracasz przez referencję, ale takie zachowanie kompilatora nie jest zgodne ze standardem. |
VC++ EE 2012: Kompilator: cannot convert parameter 1 from 'free_throws' to 'free_throws &' Intellisense: initial value of reference to non-const must be an lvalue |
|
Monika90 |
» 2015-11-16 21:16:52 Ich najnowszy (chyba) kompilator 19.00.23427.0(x86) Update 1 RC, produkuje tylko ostrzeżenie Compiled with /EHsc /nologo /W4 /c main.cpp main.cpp(8): warning C4239: nonstandard extension used: 'argument': conversion from 'X' to 'X &' main.cpp(8): note: A non-const reference may only be bound to an lvalue
Compilation successful!
Formalnie takie zachowanie jest zgodne ze standardem, w poście wyżej chodziło mi o to, że program który z tego rozszerzenia korzysta nie jest napisany w standardowym C++. |
|
j23 |
» 2015-11-17 10:56:48 Sprawdziłem na nowszej wersji środowiska - VS Community 2013 (kompilator 18.00.31101). Wyszły te same błędy co w VS 2012 EE. Nie chce mi się wierzyć, żeby w następnej wersji kompilatora o tak zmienili podejście do tego typu konstrukcji. Jeśli kompilujesz w innym IDE, dodaj opcję /Za. |
|
« 1 » 2 |