Vraag Verander retourwaarde van fundamenteel type en klassentype


Er is zo'n code:

#include <iostream>
#include <string>

int returnnumber() { return 2; }
std::string returntext() { return "siema"; }

int main() {

    std::cout << (returntext() += "cze") << std::endl; // siemacze
    //std::cout << (returnnumber() += 2) << std::endl; error: lvalue required as left operand of assignment

    return 0;
} 

Waarom is het mogelijk om de retourwaarde van std :: string te wijzigen, maar niet int?


11
2017-10-22 17:08


oorsprong


antwoorden:


omdat std::string is een klassetype met een gedefinieerde += operator als lidfunctie.

en met de standaard kunt u lidfuncties op rwaarden oproepen.

een dwaze consequentie daarvan is dat

struct S { int x; };
S foo() { return S(); }

int main()
{
    foo() = S();    // OK, uses member assignment operator.
    foo().x = 666;  // !Nah, can't assign to rvalue of built-in type.
}

compilatie resultaten:

Comeau C / C ++ 4.3.10.1 (6 oktober 2008 11:28:09) voor ONLINE_EVALUATION_BETA2
Auteursrecht 1988-2008 Comeau Computing. Alle rechten voorbehouden.
MODUS: strikte fouten C ++ C ++ 0x_extensions

"ComeauTest.c", regel 7: fout: expressie moet een aanpasbare waarde zijn
      foo (). x = 666; //! Nee, kan niet toewijzen aan rvalue van het ingebouwde type.
      ^

1 fout gedetecteerd in de compilatie van "ComeauTest.c".

compilers verschillen echter (of verschillen) over hoe strikt ze deze subtiele regel toepasten, of helemaal niet.

cheers & hth.,


10
2017-10-22 17:13



De linkerkant van een toewijzingsoperator voor een ingebouwd type moet aanpasbaar zijn lvalue maar de geretourneerde waarde van een functie is altijd een rvalue als de functie geen referentietype retourneert.

operator+= is een ledenfunctie van std::string en je kunt een ledenfunctie op een rvalue van klasse type.


2
2017-10-22 17:15



Om dezelfde reden

std::string("siema") += "cze";

werken.

U bouwt een nieuw object en past het toe operator += (welke std::string heeft).

Dit proberen, werkt niet als je functie een resultaat oplevert rvalue. Het zou zijn als:

2 += 2

Je kunt hier wat mee spelen:

#include <iostream>
#include <string>

int& returnnumber() { int * k = new int; *k = 2; return *k; }
std::string returntext() { return "siema"; }

int main() {

    std::cout << (returntext() += "cze") << std::endl; // siemacze
    std::cout << (returnnumber() += 2) << std::endl; //no error
    std::string("siema") += "cze";
    return 0;
} 

Maar dit zal leiden tot een geheugenlek, dus doe het niet. Het is slechts een bewijs van het concept dat een terugkeer lvalue zou werken.


1
2017-10-22 17:18



returntext() geeft a terug std::string welke in latere stadia kunnen worden aangepast, zeg maar +=operator. Echter, hoewel returnnumber() retourneert een int, de functie zelf komt terug 2 wat is door defualt een const int en is niet veranderbaar en dat is de reden waarom compiler klaagt.


0
2017-10-22 20:58