2017-09-30 4 views
1

J'ai un ensemble de fonctions où j'emploie la spécialisation de modèle pour effectuer des transformations sur certaines valeurs. Cependant, pour beaucoup de types je veux passer les valeurs à travers inchangées.Transmission parfaite des valeurs de retour, comportement indéfini?

Pour passer une valeur inchangée, j'ai quelque chose comme la fonction suivante comme valeur par défaut:

template< typename arg > 
arg&& convert(arg&& x) 
{ 
    return std::forward<arg>(x); 
} 

Cela semble grande mais selon la réponse here il court le risque de laisser une référence boiteuse dans une déclaration comme: Si j'utilise uniquement cette fonction inline dans les arguments de fonction, est-ce que ce risque est évité?

Par exemple, puis-je lancer dans un comportement indéfini si je fais quelque chose comme ...

void foo(int&& x) 
{ 
    // Do something with x... 
} 

foo(convert(5)); 
+0

Un peu de contexte ... comme pourquoi ne pouvez-vous pas passer '5' ou utiliser' std :: move() ' – StoryTeller

+0

Dites que je voulais écrire un wrapper pour les fonctions qui ne faisaient rien à la plupart des types, mais en ajoutant tous les entiers pour une raison quelconque (ce n'est pas mon cas d'utilisation, mais disons que c'est le cas), alors je pourrais utiliser convert pour tous les arguments sans tenir compte du type (par exemple, dans quelque chose comme une fonction variadique) et écrire une spécialisation convert (x) template qui ajoute un à chaque entier. – Matt

+0

Votre code de transfert est faux, il devrait être 'std :: forward (x);'. – VTT

Répondre

3

Par exemple, puis-je lancer dans un comportement indéfini si je fais quelque chose comme ...

No. La règle, de [class.temporary], Souligné par l'auteur, est:

un objet temporaire lié à un référen Ce paramètre dans un appel de fonction persiste jusqu'à ce que le achèvement de l'expression complète contenant l'appel.

Notre temporaire (5) est lié à un paramètre de référence en un appel de fonction (à arg&& en convert()), de sorte qu'il persiste jusqu'à la fin de la pleine expression (qui est l'ensemble des foo(convert(5))). Donc, c'est bien, tant que vous ne laissez pas une référence à x échapper foo().