2010-02-07 4 views
9

Si une fonction renvoie un int, peut-elle être affectée par une valeur int? Je ne vois pas pourquoi il est trop logique d'attribuer une valeur à une fonction. J'ai remarqué que, si la fonction renvoie une référence à un int, c'est OK. Est-ce limité à int? que diriez-vous d'autres types? ou d'autres règles?Si une fonction renvoie un int, un entier peut-il lui être assigné?

int& f() {} 

f() = 1; 
+1

quel serait le point d'attribuer une valeur à une fonction? Pourquoi ne pas utiliser une variable à la place? –

Répondre

22

La première fonction renvoie une valeur de type entier, qui est valeur r. Vous ne pouvez pas attribuer à une valeur r en général. La seconde f() renvoie une référence à un entier, qui est une valeur l - donc vous pouvez l'assigner.

int a = 4, b = 5; 

int& f() {return a;} 

... 
f() = 6; 
// a is 6 now 

Remarque: vous n'attribuez pas de valeur à la fonction, vous lui attribuez simplement sa valeur de retour. Soyez prudent avec les éléments suivants:

int& f() { int a = 4; return a; } 

Vous retourner une référence à un temporaire qui n'est plus valide après le retour de la fonction. L'accès à la référence appelle un comportement indéfini.

+0

pourriez-vous expliquer pourquoi la valeur de retour est une valeur r? – skydoor

+0

La valeur de retour d'une fonction n'est pas une variable C++ appropriée, telle que 'int i;'. Ce n'est qu'une valeur temporaire. Cela ne représente pas un emplacement de mémoire. –

+1

@skydoor, il peut être résumée par * "vous ne pouvez affecter à des objets" *. Dans votre appel, la fonction renvoie une valeur qui ne correspond pas à un objet: L'entier représente * juste * une valeur abstraite.Si vous aviez, par exemple, renvoyé un 'std :: string', la valeur retournée (qui est en fait une valeur r) correspondra à un objet chaîne, et vous * pourriez * lui assigner. La même chose est vraie pour une valeur de retour 'int &'. Dans ce cas, la "valeur" renvoyée (qui est une valeur l) correspond à un int * objet *, et vous pouvez l'assigner. Un objet est nécessaire, car une affectation modifie un état stocké. –

1

Ce n'est pas limité à int seulement, mais pour les types primitifs il n'y a aucun intérêt à le faire. Il est utile lorsque vous avez vos classes

+1

Êtes-vous en train de dire qu'il est inutile de retourner une référence à un type primitif? Donc des choses comme 'operator []' de 'vector ' sont inutiles? – sepp2k

+1

Il y a beaucoup de raison de le faire (si par 'ça' vous voulez dire renvoyer une référence) - si vous avez un vecteur std :: alors les fonctions qui accèdent aux objets dans le vecteur renvoient des références int. –

+0

Dans le contexte de son exemple, – anthares

0

Si une fonction retourne un objet en valeur, la cession est possible, même si l'appel de fonction est une valeur. Par exemple:

std::string("hello") = "world"; 

Ceci crée un objet de chaîne temporaire, le mute, puis le détruit immédiatement. Un exemple plus pratique est:

some_function(++list.begin()); 

Vous ne pourriez pas écrire list.begin() + 1, car l'addition est pas possible sur itérateurs la liste, mais incrément est bien. Cet exemple n'implique pas d'affectation, mais l'affectation est juste un cas particulier de la règle plus générale "les fonctions membres peuvent être appelées sur des valeurs".

+0

C'est un cas courant? Peux-tu me donner un exemple? – skydoor

+1

Bien que je comprenne que c'est juste un exemple, notez que «++ list.begin()» n'est pas requis pour fonctionner. L'opérateur peut être implémenté comme une fonction libre qui accepte une référence non-const et échouera à se lier à l'itérateur temporaire. –

+1

Merci, je ne me souviens jamais quels opérateurs ont des fonctions membres et qui peuvent être des fonctions libres. – fredoverflow

Questions connexes