En uno de los recientes C++ 0x corrientes de aire (n3225.pdf) podemos encontrar 5.1.2/10:C++ 0x lambda capturas
Los identificadores en una captura de lista se buscan utilizando las reglas habituales para la búsqueda de nombres no calificados (3.4.1); cada búsqueda encontrará una variable con la duración automática de almacenamiento declarada en el ámbito de alcance de la expresión lambda local. Se dice que una entidad (es decir, una variable o esto) se captura explícitamente si aparece en la lista de captura de la expresión lambda.
Eso parece bastante restrictivo para mí. Por ejemplo, se parece a mí que las siguientes cosas no están permitidos:
int global;
struct s {
int x;
void memfun() {
[x,global]{};
}
};
desde x
no es necesariamente una variable con el almacenamiento automático y tampoco lo es global
. Tenga en cuenta que la intención de esta cláusula de captura es permitir que el objeto lambda almacene una copia de x
y global
que podría ser conveniente en caso de que se modifiquen en una etapa posterior. Ya soy consciente de una alternativa:
int global;
struct s {
int x;
void memfun() {
int copyx = x;
int copyglobal = global;
[copyx,copyglobal]{};
}
};
Pero esto se reduce a copias extra y placa de la caldera adicional sólo para capturar x
y global
como copia.
Además, no puedo encontrar nada concluyente en las últimas corrientes de aire sobre lo que ocurre si nombramos una referencia local en la cláusula de captura:
int main() {
int i = 0;
int &r = i;
assert([r]{return &r;}() != &i);
}
¿El objeto lambda "copiar una referencia" o "copiar un int "¿?" Si captura el objeto referido por copia, esto puede salvarnos las copias adicionales de la solución de problemas anterior.
GCC aparentemente admite todos estos ejemplos y almacena una copia de un int en el último caso (que es deseable, en mi humilde opinión). Pero me gustaría saber si este es, de hecho, el comportamiento previsto de acuerdo con los borradores de C++ 0x o simplemente una extensión de compilador, respetivamente un error de implementación.
Editar:
templatetypedef señaló 5.1.2/14, que explica lo que sucede cuando una referencia se nombra en una cláusula de captura. Por lo que yo puedo decir, esto nos permite utilizar la siguiente solución temporal para el primer ejemplo:
int global;
struct s {
int x;
void memfun() {
auto& cx = x;
auto& cglob = global;
[cx,cglob]{};
}
};
Tia, sellibitze
Nota: C++ 14 extendió el conjunto de posibles cláusulas de captura – sellibitze