61 votes

Est-ce que [=] impliquent que toutes les variables locales seront copiés?

Quand j'écris un lambda [=], ça veut dire que toutes mes variables locales seront copiés dans les membres à la création de la structure ou puis-je penser que seuls ceux-ci qui sont effectivement utilisés dans le lambda? Par exemple:

void f()
{
    vector<int> v(10000);
    const int n = 5;
    const int DivByNCnt = count_if(istream_iterator<int>(cin), istream_iterator<int>(), 
          [=](int i)
          {
             return i % n == 0;
          });
}

Lequel des énoncés suivants est vrai?

  • n et v seront copiés
  • n sera copié, v ne sera pas
  • n sera copié, v peut ou ne peut pas être copié en fonction de la implmenentation/paramètres d'optimisation.

Supposons que pour la commodité du raisonnement que le vecteur du constructeur de copie a des effets secondaires.

63voto

Kerrek SB Points 194696

Pas de. Cela signifie simplement que toutes les variables locales de la température ambiante de la portée sont disponibles pour la recherche à l'intérieur du corps de la lambda. Seulement si vous vous référez à un nom d'une ambiance locale de la variable cette variable à être capturé, et il va être capturé par valeur.

La "capture rien" les expansions = et & sont tout sucre syntaxique, essentiellement, de dire au compilateur "comprendre ce que je veux dire".


Un officiel de référence à partir 5.1.2/11-12:

Si une lambda-expression est associée à une capture par défaut et ses composés-déclaration odr-utilise [...] une variable automatique de la durée de stockage et les odr-utilisé entité n'est pas explicitement capturé, alors l'odr-utilisé entité est dit implicitement saisis [...]

Une entité est capturé s'il est capturé, explicitement ou implicitement.

Notez que "capture par défaut" désigne [=] et [&]. Pour répéter, la spécification d'une capture par défaut ne capture rien; seulement odr-à l'aide d'une variable.

22voto

Matthieu M. Points 101624

Non! (heureusement)

Vous pouvez instrument de votre code pour vérifier si votre compilateur ne fait (ou pas). Par exemple gcc 4.8.0 semble être conforme.


Quant à ce que le Standard de fait des mandats de travail (en arrière):

§5.1.2/14 Une entité est capturé par copie si elle est implicitement saisis et de la capture par défaut est = ou si elle est explicitement capturé avec une capture qui ne comprennent pas d' &. Pour chaque entité capturé par copie, un sans nom non membre de données est déclarée à la fermeture type.

$5.1.2/11 Si une lambda-expression est associée à une capture par défaut et ses composés-déclaration odr-usages (3.2) this ou une variable de stockage automatique de la durée et de l'odr-utilisé entité n'est pas explicitement capturé, puis l'odr-utilisé entité est dit implicitement saisis; ces entités sont à déclarer dans la réalisation de la portée de l'expression lambda.

§5.1.2/9 Une lambda-expression dont le plus petit cadre englobant est un bloc de portée (3.3.3) est une expression lambda; toute autre lambda-expression ne doit pas avoir une capture, dans le lambda-introducteur. L' parvenir à la portée d'un local expression lambda est l'ensemble de l'enfermer étendues jusqu'à et y compris l'enfermer les plus secrets de la fonction et ses paramètres. [ Note: Ce large spectre comprend tout intervenant lambda-expressions. -la note de fin ]

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