c++ lambda language-lawyer c++17

c++ - Referencia local a std:: cout capturada por lambda sin solicitarla



language-lawyer c++17 (1)

¿He perdido la cabeza? ¿Esto siempre fue permitido?

#include <iostream> int main() { auto& os = std::cout; auto write = []() { os << "what/n"; }; write(); }

Estoy usando:

Apple LLVM versión 10.0.0 (clang-1000.10.44.4)
Objetivo: x86_64-apple-darwin17.7.0

Aunque también ver en Coliru:

( demostración en vivo )

Siempre pensé que una captura vacía no capturaría nada.

De hecho, MSDN says :

Una cláusula de captura vacía, [], indica que el cuerpo de la expresión lambda no tiene acceso a ninguna variable en el ámbito de cierre.

Investigaciones posteriores sugieren que, de hecho, esto está bien para capturar cosas const (que tampoco sabía, pero como sea), pero os no es const (¡no hay referencia! Aunque es inmutable ...).

Me di cuenta de esto cuando -Wextra y -Wextra que Clang pensaba que la captura de un sistema -Wextra (que está presente en mi código real) era innecesaria. Quitarlo me sorprendió encontrar la construcción funcionada.


Hay un informe de análisis abierto que cubre el caso de la captura implícita de referencias por las expresiones lambda, esto no se limita a std::cout sino a la variable de referencias que se encuentra que se refiere a expresiones constantes.

Para obtener más información, el informe de defectos de respaldo en el CWG es CWG-1472

EDITAR:

Basándome en el comentario de @ Rakete1111, debería haber señalado explícitamente que clang tiene razón al aceptar el código, que es el resultado de aplicar el defecto CWG mencionado anteriormente. El informe se reabrió debido a la ubicación del diagnóstico, no porque estuvieran equivocados sobre la aceptación