J'ai le code suivant:
Name is "� @" pName is "Ternary Return Test"
4 Réponses :
Mais ce n'est pas le cas - je retourne une référence à une valeur non temporaire, qui devrait être parfaitement valide. P> blockQuote>
Vous seriez, mais vous n'avez plus de valeur non temporaire. [EXPR.COND] /4.3 a P>
Si E2 est une pr devalue ou si aucune des séquences de conversion ci-dessus peut être formée et au moins un des opérandes a (éventuellement qualifié de CV) de type de classe: p>
- Si T1 et T2 sont le même type de classe (ignorant la qualification CV) et T2 est au moins comme CV-qualifié que T1, le type cible est T2, LI> ul> blockQuote>
Et ce que cela se résume à ce que le troisième opérande est une pr devalue, toute l'expression est une pr devalue qui signifie que vous avez toujours un comportement indéfini lorsque vous retournez toujours une référence à une référence temporaire. P>
Type d'opérateur ternaire pour
donc il est équivalent à Donc, vous renvoyez la référence de la variable temporaire ( Si vous avez utilisé Une solution peut être; p> de sorte que les deux côtés sont de lvalue et le type commun est maintenant pname? * PNAME: "(Sans nom)" code> est
std :: string code> (nous avons
std :: string & code> et
const char * cod>) p>
pname? std :: string {* pname}: std :: string {"(Sans nom)"} code>. p>
si code> au lieu de ternaire, vous auriez votre erreur attendue p> < PRE> XXX PRE>
const std :: string & code> (
std :: string & code> et
const std :: string & code>). p> p>
Comme Yksisarvinen souligne, le problème est un problème de vie. correction: p> "(Sans nom)" code> a une durée de stockage statique, mais ce n'est pas ce que vous revenez. Vous revenez
std :: string {"(Sans nom)"} code> et une référence à être exact. Cette temporaire sans nom disparaît avant même que la fonction revienne même.
Et le problème est également avec * pname code> qui se transforme également en
std :: string {* pname} code> parce que l'opérateur ternaire.
@ Jarod42: Pourquoi? * pname code> et
defaultValue code> sont du même type, et les deux sont des glvalues. Ceci est équivalent à
* (pname? Pname: & DefaultValue) code>.
@walnut: Yeah, "Sans nom" code> peut être utilisé pour initialiser un
consexpr code> défaut mais qui n'a pas résolu le problème réel. Vous avez besoin d'un
static const std STD :: chaîne code>.
@walnut: Pas assez de café pour un lundi: |
J'ai parlé de l'affaire OP, pas la solution fixe. Nous pourrions lire votre explication comme un problème est uniquement lorsque vous renvoyez "(Sans nom)" code> mais de l'autre côté comme un problème similaire.
Pour référence (la référence de référence en suspens est déjà décrite déjà), cela devrait probablement être quelque chose comme
Désolé, mais ce dernier commentaire n'a pas de sens. Quelle serait la mauvaise branche? * pname code> lorsque
pName == nullptr code>? C'est sûr, par intention.
* pname code> est séquencé - après le test de
pname code>.
Si vous renvoyez une référence à temporaire est UB, alors une branche serait i>, même si elle n'est jamais exécutée - est problématique. Je vais devoir penser à une meilleure façon de l'exprimer.
@ Inutile ce n'est pas correct. Vous êtes autorisé à avoir UB dans une branche tant qu'elle n'est jamais exécutée. Le compilateur doit toujours assurer qu'un programme qui ne prend jamais la branche UB s'exécute avec le comportement défini.
Si vous venez de retourner
* pname code> (pas de terne), tout va bien?
Si vous n'obtenez pas un avertissement de compilation à ce sujet, augmentez votre niveau d'avertissement.