Maison >développement back-end >C++ >C 11 Lambdas peut-il capturer des références sans invoquer un comportement non défini ?

C 11 Lambdas peut-il capturer des références sans invoquer un comportement non défini ?

Susan Sarandon
Susan Sarandonoriginal
2024-11-04 22:03:02671parcourir

Can C  11 Lambdas Capture References Without Invoking Undefined Behavior?

Capture de références en C 11 Lambdas

En C, les expressions lambda peuvent capturer des variables à partir de leur portée englobante. Cependant, la méthode de capture détermine si la variable est accessible par référence ou par valeur. Considérez le code suivant :

<code class="cpp">#include <functional>
#include <iostream>

std::function<void()> make_function(int& x) {
    return [&]{ std::cout << x << std::endl; };
}

int main() {
    int i = 3;
    auto f = make_function(i);
    i = 5;
    f();
}</code>

Ce code capture la variable x par référence en utilisant la syntaxe [&]. La question se pose de savoir si ce programme garantit la sortie 5 sans invoquer un comportement indéfini.

Réponse : Oui

Le code est garanti de fonctionner correctement. Avant d’examiner le libellé standard sous-jacent, il est important de noter que ce code fonctionne comme prévu par le comité C. Cependant, la formulation initiale de la norme C 11 n'était pas claire sur ce point, ce qui a conduit à soulever la question 2011 du CWG pour apporter des éclaircissements. Ce problème est résolu dans le développement en cours de la norme C.

Explication standard

Selon [expr.prim.lambda]/17 de la norme C, seules les expressions id faisant référence aux entités capturées par copie sont transformées en accès membre sur le type de fermeture lambda. les expressions d'identification faisant référence aux entités capturées par référence sont laissées seules et continuent de désigner la même entité qu'elles auraient désignée dans la portée englobante.

Dans le code ci-dessus, l'entité capturée est le paramètre x de la fonction make_function , qui entre dans le champ d'application du lambda. Par conséquent, la référence x dans l'expression lambda fait référence à la variable d'origine déclarée dans la fonction principale.

Il peut initialement sembler problématique que x soit référencé en dehors de sa durée de vie après le retour de la fonction make_function. Cependant, il existe des scénarios limités dans lesquels une référence peut être référencée en dehors de sa durée de vie. Généralement, une référence est soit déclarée dans sa portée, soit est membre d'une classe, auquel cas la classe elle-même doit être dans sa durée de vie.

Par conséquent, la norme n'interdit pas explicitement l'utilisation de références en dehors de leur durée de vie. Cette faille a permis de prendre en charge la capture de références par référence dans les expressions lambda.

CWG Issue 2012 and Future Clarification

CWG issue 2012 a été soulevée pour remédier à l'oubli. que les références pourraient être référencées en dehors de leur durée de vie dans certaines circonstances. La résolution de ce problème a affecté par inadvertance la spécification de la capture lambda par référence de références. Cependant, il est prévu que cette régression soit corrigée avant la sortie du C 17.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn