J'apprendais passer par référence, et voici le test que j'ai fait: et voici le résultat que j'ai obtenu: p> Si nous passons une expression constante, il déclenche toujours une référence de rvalue non constante? Sous quelle condition il va déclencher une référence de rvalue constante (et pourquoi S6 ne le triggente pas?) P> li>
Pourquoi une référence non constante et une référence de rvalue constante sont illégales? P> LI>
Je m'attendais à ce que cela ne puisse pas changer S3, mais pourquoi B dans la portée intérieure peut changer S3? Si l'attribution d'un nouvel objet S3 à B attribue une nouvelle référence, pourquoi, lorsque j'affecte S4 à elle et S3 a changé et S4 est vide par la suite? P> LI>
ol> Désolé de demander trop de questions ... Je vais augmenter les points lorsque toutes les questions sont répondues :) La référence apporte simplement ma confusion du pointeur à un tout nouveau niveau. P>
< P> Je ne sais pas comment augmenter le point ... Attendrez donc 2 jours jusqu'à ce qu'il soit éligible à une prime, puis choisissez la réponse. P> p>
5 Réponses :
RValues peut se lier à des références de rvalue et des références Cons-LValue, par exemple mais la rvalue ne peut pas se lier aux références de lvalue non constituées. La résolution de la surcharge préfère la liaison des temporaires vers RValue-Refs sur les reliures à la const-la liaison à Const Lvalue Refs: P> paramCheck(""); // a string literal is an lvalue (!)
// see [expr.prim.general]/1
// but it is implicitly converted to a `std::string`,
// creating a `string` temporary, a rvalue
paramCheck(string{""}); // a temporary is an rvalue
string s3{""};
paramCheck(s3); // the variable `s3` is an lvalue of type `string`
const string s4{""};
paramCheck(s4); // the variable `s4` is an lvalue of type `const string`
//Illegal
//string& s{""}; // can't bind a temporary to a non-const lvalue ref
//paramCheck(s);
const string& s5{s3};
paramCheck(s5); // the variable `s5` is a lvalue of type `const string`
string&& s6{""}; // binding a temporary to a rvalue-ref (allowed)
paramCheck(s6); // the variable `s6` is an lvalue (!) - it has a name
//Illegal
//const string&& s{s1}; // `s1` has not been declared
//onstFP(s);
//Reference test
string a = s3; // copy the contents of `s3` to a new string `a`
a = "a changed s3"; // overwrite contents of `a`
cout << s3;
{
string& b = s3; // `b` refers to `s3` now (like an alias)
b = "b changed after assigning s3\n";
cout << "s3 is now " <<s3;
b = s4; // copy the contents of `s4` to `b` (i.e. to `s3`)
b = "b changed after assigning s4\n";
cout << "s3 is now " <<s3;
cout << "s4 is now " <<s4;
}
Si nous passons une expression constante, il déclenche toujours une référence de rvalue non constante? Sous quelle condition il va déclencher une référence de rvalue constante (et pourquoi S6 ne le triggente pas?) P>
Pour une expression constante? Rien. La seule fois où quelque chose se liera à
const && code> sera s'il est déjà
const code>. Et même alors, cela nécessitera une distribution explicite s'il s'agit d'une variable (voir ci-dessous). P>
Pourquoi une référence non constante et une référence de rvalue constante sont illégales? P> blockQuote>
Je vais supposer que vous parlez de ceux-ci: p>
xxx pré> Le premier est illégal car
"" code> n'est pas un
std :: chaîne code> variable. Par conséquent, il doit construire un
std :: chaîne code> temporaire de
"" code>.
s code> est une référence non-const à une chaîne existante variable em>. Vous ne pouvez pas faire une référence non-const à une référence temporaire, car une variable n'est pas une variable. P>
La seconde est illégale parce que (ignorant le fait que
S1 code> n'existe pas ) C ++ ne vous permet pas d'obtenir une référence de valeur R à une variable sans conversion em> explicite em>. C'est ce que
std :: déplacer code> est pour.
const string && s {std :: move (S3)} code> fonctionne juste bien. P>
Je m'attendais à ne pas changer S3, mais pourquoi B dans la portée intérieure peut changer S3? Si l'attribution d'un nouvel objet S3 à B est attribuant une nouvelle référence, pourquoi, lorsque j'affecte S4 à elle et S3 a changé et S4 est vide ensuite? P> blockQuote>
Tout d'abord, vous pouvez modifier
S3 code> bien.
B code> est un référence em> à
S3 code>; Ils sont deux noms pour le même objet. Quant au reste, vous ne pouvez pas modifier quel objet est référencé par
B code> après
B code> est créé.
B CODE> Démarre le référencement de référence
S3 code>, il sera donc toujours em> le faire. Ainsi,
b = s4 code> signifie copier
s4 code> dans tout objet est référencé par
b code>, qui est
s3 code>. p>
S4 code> est vide après parce qu'il était toujours vide em>. Vous avez attribué la chaîne vide em> à elle. Donc, c'est vide. P> blockquote>
D'abord le code
paramCheck(""); //constructs a temporary. temporaries bind to `string&&` paramCheck(string{""}); //constructs a temporary. temporaries bind to `string&&` string s3{""}; paramCheck(s3); //passes a reference to an existing string: `string&` const string s4{""}; paramCheck(s4); //passes a reference to an existing string+const: `const string&` //Illegal //string& s{""}; //cannot assign a temporary to a non-const l-reference //what would s refer to when the temporary "dies"? //`const string&` would have worked though //paramCheck(s); //passes a reference to an existing string+const: `const string&` const string& s5{s3}; //s5 is s3, but with `const`. paramCheck(s5); //passes a reference to an existing string+const: `const string&` string&& s6{""}; //r-references extend the life of temporaries. paramCheck(s6); //passes a reference to an existing strong: `string&` //const string&& s{s1}; //temporaries can be extended by `T&&` or `const T&` only. //Reference test string a = s3; //a is a _copy_ of s3 a = "a changed s3"; //so changing the copy doesn't effect the origional. cout << s3; //s3 is still blank, it hasn't changed. { string& b = s3; //b isn't really a "reference" to `s3`". `b` _IS_ `s3`. b = "b changed after assigning s3\n"; //since `b` IS `s3`, this changes `s3`. cout << "s3 is now " <<s3; b = s4; //`b` _IS_ `s3`, so you just changed `s3` again. b = "b changed after assigning s4\n"; cout << "s3 is now " <<s3; cout << "s4 is now " <<s4; //s4 is still blank, it hasn't changed. }
Je n'ai pas l'impression que cela va être considéré comme un commentaire constructif selon les règles de SOF, mais j'ai besoin de dire que j'aime apprendre et effacer des choses à travers vos réponses @MOOKing Duck. Vous expliquez les choses pleinement et d'une manière qui a du sens pour moi. Je sais que je ne suis pas le seul à savoir de cette façon et si mon fonctionnement n'a pas bloqué la fonction de discussion de SOF, je l'aurais fait dans un cadre plus approprié. Mais merci pour l'aide que vous m'avez donnée, que ce soit directement ou non. Mes emails de mon profil et j'aimerais discuter avec vous de codé de temps en temps si vous êtes prêt. :)
"Il existe des moyens de déclencher const string && code>, mais il n'y a aucune raison de le faire de ce jour, donc ça n'a pas d'importance." I> homme, c'était une telle déception. Souhaitez-vous expliquer comment de toute façon? :)
@Mehrdad: a édité les deux manières qui se viennent immédiatement à l'esprit dans la question, bien que je suis sûr qu'il y a d'autres. Calling std :: Déplacer code> sur une variable Conscons fonctionne probablement par exemple. Les trois manières sont assez explicites, vous ne les trouverez probablement pas accidentellement
@MOOINGDUCK: cool, +1.
@Dan: C'est toujours incroyable d'obtenir des commentaires comme ça. Vous vous êtes gagné une citation sur mon profil: D
Depuis que nous avons déjà une référence de const, pourquoi avons-nous besoin de référence de rvalue?
Vous devriez arrêter de penser à une fonction prenant Ce marquage temporaire ne dure pas. Si vous avez une variable Les moyens standard de marquer des données comme temporaire sont à (a) c'est une instance anonyme de En pratique, En bref: il y a quatre spots valides communs à utiliser Lorsque vous utilisez une variable nommée foo && code> comme référence de rvalue. Pensez plutôt à ce que les choses se lient. P>
foo && code> ne se liera que pour temporaire
foo code> s, ou
foo code> s marqué comme temporaire. p>
foo && foo code>, et que vous l'utilisez, il n'est pas marqué comme temporaire au point d'utilisation. Marquer quelque chose comme étant un temporaire ne peut se produire immédiatement - par une fonction qui renvoie un
foo && code> ou en renvoyant un anonyme
foo code> qui, dans son utilisation immédiate, est considéré comme temporaire . p>
FOO code> temporaire, (B) que vous avez appelé
std :: Déplacer code> Sur une instance de
foo code>, (c) appelé
std :: transfert
foo code>. p>
&& code> est utilisé à la fois par ce que l'on appelle les références universelles et par des références que vous souhaitez lier aux temporaires. Dans un contexte de déduction de type, les références de lvalue peuvent être stockées dans un
t && code> en faisant
t code> dans
foo & code> - la référence de lvalue "gagne" sur le Revalue référence. C'est la situation où vous devez appeler
std :: avant code> afin de déplacer conditionnellement. P>
&& code>. p>
pour (auto && i: x) code>). Li>
ul>
&& code>, il agit presque exactement comme un
& code> ou
Const & code> variable. Afin de l'utiliser de manière à traiter comme temporaire, vous devez
std :: Déplacer Code> ou dans un contexte de référence universel, utilisez
std :: Transférer code> à Conditionnellement
std :: Déplacer code>. P>
Juste pour répondre à cette partie:
Sous quelle condition il va déclencher une référence de rvalue constante p> blockQuote>
La surcharge de référence de rvalue constante sera utilisée lorsque vous l'appelez avec une rvalue de type constant: p>
xxx pré> dans les fonctions générales prenant un
const x && code> sont inutiles, car vous ne pouvez pas passer d'une constante. Ils peuvent être utiles comme des fonctions supprimées afin d'empêcher certains appels de compilation. P> p>
Il n'y a pas de Références de références i> en C ++. La syntaxe
&& code> se réfère à une référence de rvalue ou à une référence universelle (dans les modèles).
En référence de la référence, vous voulez dire RValue-Référence. La norme appelle spécifiquement des références aux références ne sont pas autorisées. Juste FYI. C ++ 11 § 8.3.2, P5: "Il n'y aura aucune référence aux références, aucun tableau de références et aucun point de référence de références. ..." I> abrégé pour .. bien .. Brevity .
@Dyp true, malgré le fait que les références universelles n'existent pas réellement. ;)
"Il déclenche toujours une référence de rvalue constante" non, votre code jamais i> a déclenché la référence de rvalue constante. Il toujours i> trigued la référence de rvalue non-const.
La référence non-Const n'est pas illégale. const r-valeur semble un peu bizarre
@MOOINGKUCK UNE AUTRE TYPO. Corrigée