2017-08-31 8 views
0

en se référant au code suivant:fonction C++ et rvalue confusion

// Example program 
#include <iostream> 
#include <string> 
using namespace std; 

struct S 
{ 
    S() 
    { 
     cout << "ctor\n"; 
    } 
    S(S&& rhs) 
    { 
     cout << "called move\n"; 
    } 
}; 

S goo() 
{ 
    S a; 
    return a; 
} 

int main() 
{ 

S&& goo(); 
cout << "before construction\n"; 
S a = goo(); 

} 
//http://thbecker.net/articles/rvalue_references/section_05.html 

pourquoi le code appelant la move constructor et non la fonction S goo()? Si vous commentez la première ligne, ce n'est pas le cas.

pourquoi le type de retour de S goo() est-il différent selon la première ligne dans main? Je ne pense pas que cela devrait même compiler mais compilera ici http://cpp.sh/22zeq

(ne compile pas sur wandbox: https://wandbox.org/permlink/3YxBdcWs91FRiODG)

a été la lecture d'un exemple ici: http://thbecker.net/articles/rvalue_references/section_05.html quand je suis tombé sur ce

+4

Que pensez-vous de 'S && goo();' dans votre main? – SergeyA

+0

@SergeyA Il n'y a pas de définition de 'S && goo()' alors comment ça marche? – PYA

Répondre

1

Il est parce que S&& goo(); est la déclaration de nouvelle fonction. Mais quand vous compilez il n'existe qu'une seule fonction avec un tel nom S goo(); c'est pourquoi il a été appelé.

C'est un travail de lieur. Il n'a trouvé aucune autre fonction avec un tel nom et lié à S goo();

+0

Il n'y a pas de définition de 'S && goo()' alors comment ça marche? – PYA

+0

@pyjg C'est facile. Quand arrive l'appel du compilateur de fonction ajouté dans ce lieu d'appel nom symbolique goo. Ensuite, l'éditeur de liens essaie de trouver par signature une fonction et trouve S goo(), puis le remplace par l'adresse de cette fonction. Ce problème se produit parce que la valeur de retour ne fait pas partie de la signature de la fonction –

+0

@pyjg Cela arrive parce que pour le compilateur c'est une autre fonction, mais pour l'éditeur de liens n'existe qu'une telle fonction 'goo()' ['S goo()'] –

1

Le type de retour est différent parce S&& goo(); est une déclaration de fonction . Ainsi, il ne construit rien.

Il indique au compilateur que goo est une fonction qui retourne S&& et ne prend aucun argument. Cela écrase toutes les autres déclarations précédentes, donc, pour la fonction main, goo renvoie S&&. Lorsque vous commentez cette ligne, seule la définition de la fonction définit le type de retour. Ceci fonctionne également sur Ideone. C'est-à-dire qu'à l'intérieur de main le type de retour de goo a changé pour S&&.

2

Puisque tout le monde semble comprendre ce que fait S&& goo(); dans le principal (il déclare une fonction) mais les gens ne semblent pas comprendre comment s'appelle S goo() à la fin.

La raison en est que la valeur de retour ne fait pas partie de la signature de la fonction. Ainsi, lorsque vous appelez goo(), vous finissez par appeler la seule version qui est disponible - une qui renvoie S. Je crois, ceci est un exemple de comportement indéfini.

+0

merci pour la réponse. Ne devrait pas être un bug? – PYA

+0

@pyjg un bug votre code? Je crois, c'est. – SergeyA

+1

@SergeyA Non, je crois que OP fait référence à la façon dont le compilateur laisse une telle surcharge ambiguë être déclarée. Il peut être défini dans une autre unité de traduction oui, mais il n'est pas viable d'être surchargé en premier lieu. Clang rejette le code correctement https://wandbox.org/permlink/pwYSWrxoHNLEDOs6 – Curious