2017-02-02 5 views
3

solution Trouvé comment utiliser rvalue comme lvalue:rvalue comme lvalue

&(std::string()=std::string("Hello World")); 

mais pas sûr est-il légal d'utiliser cette construction.

même code à ce travaille pour moi

typedef std::pair<const char *, const std::string *> custom_pair; 

std::ostream & operator <<(std::ostream & os, const custom_pair & kv) 
{ 
    if (kv.first && kv.second && !kv.second->empty()) 
     os << kv.first << *kv.second; 

    return os; 
    } 

std::ostringstream q; 
q << custom_pair("example_string=", &(std::string() = IntToString(1))); 

où le constructeur a besoin custom_pair adresse en tant que deuxième paramètre, mais quelqu'un peut-il expliquer est-il correct d'utiliser?

+1

Montrer en quoi 'custom_pair()' est réellement disponible. Fournissez un [MCVE] au besoin! Gardez vos questions autonomes, au lieu de renvoyer uniquement aux liens (ils peuvent être utilisés comme informations supplémentaires). –

+2

Cela semble être un problème. Stocker l'adresse d'un objet temporaire? – tadman

+0

* Code identique à ceci fonctionne pour moi * Que signifie * travail * dans votre cas? Je suppose que vous allez rencontrer UB si vous déréférencer le pointeur. –

Répondre

2

Tout va bien dans votre cas d'utilisation. L'objet temporaire est détruit au point-virgule après l'opération "< <". À ce moment-là, il n'est plus utilisé.

Veillez à ne pas utiliser ce modèle lorsque le pointeur peut encore être utilisé après la destruction du temporaire.

Cela dit, je n'accepterais pas ce code dans une revue de code. Tout le monde lisant cela aurait trop de mal à déterminer pourquoi cela fonctionne. Comme vous pouvez le voir par les commentaires ci-dessous votre question.

+0

Ouais, je comprends, ça ressemble à des conneries, mais ça me motive à faire cette réponse –

0

trouvé solution de contournement comment utiliser rvalue comme lvalue

Vous n'avez pas besoin solution de contournement sur la façon d'utiliser rvalue comme lvalue, mais plutôt corriger votre code que vous n'avez pas besoin de cette solution de contournement. Par exemple le deuxième type de la paire devrait être std::string, pas const std::string * et tous vos problèmes partiraient.

+0

C'est un bon conseil, mais dans ce cas on fait une copie d'objet, donc ce n'est pas optimal en mémoire en utilisant le paramètre, non? –

+0

@ ВсеволодИвшин Optimisation prématurée classique –

+0

@ ВсеволодИвшин "l'optimisation prématurée est la racine de tous les maux". Avant toute chose, si vous ne le "convertissez" pas en lvalue, vous le déplacerez efficacement dans le paramètre. Votre code sera donc propre, lisible et toujours rapide. – Slava

2

mais je ne suis pas sûr qu'il est légal d'utiliser cette construction.

Vous êtes à la limite de l'exécution dans UB.

std::ostringstream q; 
q << custom_pair("example_string=", &(std::string() = IntToString(1))); 

fonctionne bien puisque tous les objets temporaires sont encore en vie lorsque le pointeur est déréférencé. Remplacez cela par:

std::ostringstream q; 
custom_pair p("example_string=", &(std::string() = IntToString(1))); 
q << p; 

et vous êtes soudainement en territoire UB.