¿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.
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.
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 ]
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