2 votes

Y aura-t-il une solution temporaire pour la valeur retournée qui est détruite ?

Je suis un peu confus au sujet des nouvelles règles concernant l'élision de la copie et je ne suis même pas sûr qu'elles s'appliquent dans ce cas. J'ai ceci :

template <typename T> struct foo {
    T t;
    foo(const T& t) : t(t) {}
    ~foo() { std::cout << "destructor \n"; }
}

template <typename T> foo<T> make_foo(const T& t) { return {t}; }

donde make_foo est seulement pour permettre de déduire le paramètre (dans le code réel t est un lambda, mais je l'ai laissé ici par souci de simplicité, ou plutôt par souci de confusion, désolé pour cela) comme dans

auto x = make_foo(123);

Maintenant, j'ai besoin d'être absolument sûr que foo est appelé exactement une fois : lorsque x sort du champ d'application. Je crains que cette question ne soit pas très claire, mais s'il est si évident qu'il n'y aura pas d'interruption temporaire de l'activité de l'entreprise, je ne vois pas pourquoi. foo ce serait une réponse suffisante ;).

En C++11, puis-je être certain qu'il n'y aura pas d'erreur d'affichage temporaire ? foo en make_foo qui seront détruites ? Le destructeur ne doit être appelé que lorsque x sort du champ d'application.

Comme cela a été correctement souligné dans un commentaire, cette question est la partie Y d'une question XY et la partie X est que je veux mettre en œuvre une fonctionnalité de fin de portée. Le destructeur de foo a des effets secondaires (dans l'exemple, le cout ) qui doit être appelé à la fin de la portée de l'élément x mais pas dans make_foo au cas où il y aurait un problème temporaire foo .

2voto

Yola Points 2650

Dans C++11, l'élision de copie, même pour les temporaires sans nom, n'est que permise et non obligatoire. Elle est décrite ici élision de la copie . Il est obligatoire depuis C++17.

De plus, en C++17, vous aurez des guides de déduction automatique, donc vous n'aurez pas besoin d'une telle construction.

Et vous pouvez tester votre compilateur, car la plupart des compilateurs modernes éludent la copie ici.

1voto

Matt McNabb Points 14273

Depuis C++17, il est garanti qu'il n'y a pas de temporaire.

En C++14 et antérieur, il doit y avoir un constructeur de copie/déplacement accessible, et il est facultatif pour le compilateur de savoir s'il y a effectivement un temporaire ou non.

Pour autant que je sache, le seul compilateur qui manifesterait réellement un temporaire est une ancienne version de MSVC en mode Debug.

1voto

toozyfuzzy Points 440

Dans votre cas, pour être sûr que le destructeur ne sera pas appelé pour un objet non nommé, vous pouvez lier la valeur de retour à l'adresse suivante référence constante . Pour clarifier ce qui se passe si nous ne comptons pas sur l'élision de la copie :

template <typename T> foo<T> make_foo(const T& t) { return {t}; }

Dans cette fonction, l'objet de retour ne sera pas construit dans la portée de cette fonction. Elle créera objet temporaire sans nom hors du champ d'application. Si vous liez la valeur de retour à un nouvel objet nommé le constructeur move sera appelé (ou copié si move n'est pas défini) pour créer votre nouvel objet de retourné temporaire . Cependant, si vous liez le temporaire retourné à référence constante il sera strictement lié à cette référence et aucun nouvel objet ne sera construit et les objets temporaires ne seront pas détruits tant que cette référence ne sera pas sortie de la portée.

EDIT : Pour ne pas vous induire en erreur. Le constructeur d'une référence temporaire est appelé dans la portée de la fonction, mais la durée de vie de cette référence temporaire sera en effet prolongée jusqu'à la durée de vie de la référence constante.

Si vous avez besoin de plus d'informations, vous pouvez consulter cette réponse. Elle fait référence à la norme C++.

Est-ce qu'une référence constante prolonge la vie d'un temporaire ?

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X