web-dev-qa-db-fra.com

Pourquoi pas une référence non-const à des objets temporaires?

Duplicata possible:
ne référence const prolonge-t-elle la vie d'un temporaire?
prolongeant la durée de vie des temporaires

C++ autorise l'affectation d'objets temporaires uniquement à la référence const. Il ne permettra pas l'attribution d'objets temporaires à référencer.

Par exemple:

String& a = String("test");         // Error
const String& a = String("test");   // Ok

Partout où je google pour ce résultat, je ne vois que les réponses suivantes

  1. La modification d'objets temporaires entraînerait des problèmes non identifiables
  2. La modification d'objets temporaires est dangereuse
  3. À un moment donné, vous oublierez qu'il s'agit d'une variable temporaire

Il a été dit que des objets temporaires disparaissent après la déclaration. Vous ne devez donc pas le modifier.

Si C++, est si désireux de bloquer la modification des objets temporaires, il aurait dû bloquer la lecture des objets temporaires non? Si l'objet temporaire a disparu, alors il ne sert à rien de lire le contenu à partir de là, non? Les cas possibles, où un droit peut se produire, pourraient également impliquer la lecture.

Alors pourquoi bloque-t-il l'écriture seule et autorise-t-il la lecture?

Veuillez me donner une explication solide du code c ++.

Veuillez ne pas dévier la question en pointant quelques alternatives. Veuillez me donner une réponse solide avec le code pourquoi const int & est autorisé et int & n'est pas autorisé pour les objets temporaires.

On dit && est là .. Ma question est différente .. ANother disons, changer ne reflètera pas .. Changer ne reflètera pas même quand il est constant & aussi. Par exemple: double a; Const int & i = a; a ++; n'affectera pas i ..

47
user738471

Le cas d'origine pour ne pas autoriser les références aux temporaires était pour les paramètres de fonction. Supposons que cela soit autorisé:

void inc(double& x)
{ x += 0.1; }

int i = 0;
inc(i);

Pourquoi i n'est-il pas modifié?

30
Bo Persson

Si C++, est si désireux de bloquer la modification des objets temporaires, il aurait dû bloquer la lecture des objets temporaires non? Si l'objet temporaire a disparu, alors il ne sert à rien de lire le contenu à partir de là, non?

Non, la lecture de l'objet est parfaitement sensée. Ce n'est pas parce que cela va disparaître à l'avenir que la lecture des données maintenant est inutile.

open_file(std::string("foo.txt"));

std::string("foo.txt") est un temporaire qui cessera d'exister après l'appel à open_file() mais les données qu'il contient alors qu'elles existent sont très importantes.

La raison pour ne pas autoriser les temporaires à se lier à des références non const n'est pas en fait un problème fondamental avec l'écriture dans les temporaires. En fait, dans de nombreux endroits, C++ est parfaitement heureux de permettre la modification des temporaires:

std::string("foo") = "bar";

C'est juste que les concepteurs ont estimé que cela causerait un nombre suffisant de problèmes (probablement en raison de l'idiome commun des `` paramètres de sortie '') sans permettre quoi que ce soit de valeur similaire, alors ils ont simplement pris une décision de conception pour interdire la liaison temporaire à des éléments non const. références.

Avec les références rvalue, vous pouvez maintenant faire exactement ce qui était interdit auparavant:

void foo(int &&output) {
    output = 1;
}

foo(2);

Cela fonctionne bien, ce n'est tout simplement pas très utile.

13
bames53

Si vous avez un objet temporaire très coûteux à copier, vous préférerez peut-être prendre un const& à cet objet (disons un retour de fonction) plutôt que de le copier dans une autre variable pour l'utiliser plus tard. La prise d'une référence constante à un temporaire prolonge la durée de vie de ce temporaire jusqu'à la durée de vie de la référence, vous permettant d'accéder à n'importe quel état lisible.

L'écriture est interdite, car dès que vous voulez muter une variable, vous pouvez également avoir une instance réelle plutôt qu'un temporaire qui n'est aliasé que comme référence non const.

3
Mark B

Il y a une raison logique à cela. Pensez à ce que vous voulez réellement dans cette ligne:

String& a = String("test");         // Error

Vous voulez une référence. Une référence se rapporte à l'objet auquel elle fait référence. Comme une adresse de l'objet (bien que les références ne soient pas des adresses, cela rend l'explication plus claire de cette façon). Vous essayez en fait d'obtenir quelque chose comme une adresse de String("test"). Mais cet objet disparaîtra directement sur la ligne suivante, alors à quoi sert son adresse, si l'objet vers lequel il pointe n'existe pas? a pointe maintenant vers quelque chose de vide de sens ...

Concernant votre deuxième question, quel est l'intérêt de permettre des objets temporaires ensemble, eh bien, il n'y a rien de mal à cela. Prenons par exemple le cas où vous souhaitez passer un objet String à une fonction, qui retourne, disons, une chaîne modifiée correspondant à cette chaîne. Appelons la fonction DoubleString, donc au lieu de le faire

String s("hello ");
String s2 = DoubleString(s);

Vous pouvez utiliser un formulaire plus court et plus pratique

String s2 = DoubleString(String("hello "));

Vous voyez, l'objet temporaire String("hello ") survit à toute la ligne de code, ce qui signifie qu'il est intact lorsqu'il est envoyé à DoubleString et après. Il n'est détruit que lorsque toute la ligne est terminée.

0
Israel Unterman