¿Implica [ = ] que todas las variables locales serán copiadas?


Cuando escribo una lambda con [=], ¿significa que todas mis variables locales se copiarán en miembros de la estructura creada o puedo asumir que solo aquellas que se usan realmente en la lambda? Por ejemplo:

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;
          });
}

¿Cuál de los siguientes, si alguno, es verdadero?

  • tanto n como v serán copiados
  • n se copiará, v no
  • n se copiará, v puede o no copiarse dependiendo de la implementación / optimización configuración.

Supongamos por el bien del argumento que el constructor de copia de vector tiene efectos secundarios.

Author: Armen Tsirunyan, 2013-03-25

2 answers

No. Solo significa que todas las variables locales del ámbito ambiente están disponibles para su búsqueda dentro del cuerpo de la lambda. Solo si se refiere a un nombre de una variable local ambiental, esa variable será capturada, y será capturada por valor.

Las abreviaturas de "capturar cualquier cosa" = y & son solo azúcar sintáctica, esencialmente, diciéndole al compilador que "averigüe lo que quiero decir".


Una referencia formal de 5.1.2 / 11-12:

Si a lambda-expression tiene asociado capture-default y su compound-statement odr-uses [...] una variable con duración de almacenamiento automático y la entidad odr-utilizada no es capturada explícitamente, entonces la entidad odr-utilizada se dice que es capturada implícitamente [...]

Una entidad es capturada si es capturada explícita o implícitamente.

Tenga en cuenta que " capture-default" se refiere a [=] y [&]. Para repetir, especificando una captura por defecto no captura nada; solo odr-usando una variable lo hace.

 63
Author: Kerrek SB,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-03-25 10:33:00

¡No! (afortunadamente)

Puede instrumentar su código para verificar si su compilador realmente lo hace (o no). Por ejemplo gcc 4.8.0 parece ser compatibles.


En cuanto a lo que el Estándar realmente exige (trabajar hacia atrás):

§5.1.2/14 Una entidad es capturada por copia si es capturada implícitamente y la captura por defecto es = o si es capturada explícitamente con una captura que no incluye un &. Para cada entidad capturada por copy, se declara un miembro de datos nonstatic sin nombre en el tipo de cierre.

5 5.1.2/11 Si una expresión lambda tiene un capture-default asociado y su instrucción compuesta odr-uses (3.2) this o una variable con duración de almacenamiento automático y la entidad odr-usada no es capturada explícitamente, entonces se dice que la entidad odr-usada es capturada implícitamente; tales entidades serán declaradas dentro del alcance de la expresión lambda.

§5.1.2 / 9 A lambda-expression whose smallest enclosing scope is a block scope (3.3.3) is a local lambda expression; any other lambda-expression shall not have a capture-list in its lambda-introducer. El alcance de una expresión lambda local es el conjunto de ámbitos que encierran hasta e incluyendo la función que encierra más interna y sus parámetros. [Nota: Este alcance incluye cualquier expresión lambda que intervenga. -nota final ]

 22
Author: Matthieu M.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-03-25 10:41:06