examples c++ c++11 lambda constexpr

c++ - examples - Lambda captura objeto constexpr



lambda examples c++ (2)

El segundo argumento de plantilla para std::integral_constant< int, i > es para un parámetro de plantilla de tipo no tipográfico, específicamente de tipo integral o de enumeración (14.3.2p1 punto 1) y, por lo tanto, debe ser una expresión constante convertida de tipo int .

En una expresión lambda , la captura implícita se produce cuando una entidad es odr-used en la declaración compuesta (5.1.2p11); el uso de una expresión constante convertida en una instanciación explícita de plantilla no es odr-use (3.2p3), por lo que el primer ejemplo es válido.

En el segundo ejemplo, creo que gcc es incorrecto para rechazarlo; 5.1.2p17 dice en una nota que:

Una expresión-id que no es un uso de odr se refiere a la entidad original, nunca a un miembro del tipo de cierre.

Aunque el párrafo en su conjunto está discutiendo la captura por copia, no hay razón para no aplicar esta regla a la captura por referencia también. No es sorprendente que el estándar no esté claro en esto; realmente no hay razón para capturar una entidad que pueda usarse en una expresión constante convertida por referencia.

GCC 4.7.2 compila esto:

constexpr int i = 5; []{ std::integral_constant< int, i >(); }; // nonstandard: i not captured

pero no esto:

constexpr int i = 5; [&i]{ std::integral_constant< int, i >(); }; // GCC says i not constexpr

El último ejemplo me parece correcto, según C ++ 11 §5.1.2 / 15:

Una entidad se captura por referencia si se captura implícita o explícitamente pero no se captura por copia. No se especifica si los miembros de datos no estáticos sin nombre adicionales se declaran en el tipo de cierre para las entidades capturadas por referencia.

Parece que el objeto capturado i dentro de la lambda se refiere a la variable en el ámbito de constexpr , que es constexpr , no simplemente una referencia const .

El estándar dice explícitamente que el uso de una captura por valor se transforma en un uso del miembro correspondiente del objeto lambda. Y creo que 5.1.2 insinúa que mi interpretación es correcta.

¿Hay algo que diga explícitamente que si una captura por referencia se refiere al objeto en el ámbito de cierre o una referencia?


Primero, puedo confirmar tu observación con gcc 4.6.3 y clang 3.0 en Ubuntu 12.04.

No tengo el estándar C ++ 11 (solo borrador), así que no puedo comentar sobre eso. Pero mira, desde mi entendimiento, declaraciones equivalentes

constexpr int i = 5; const int &j = i; std::integral_constant<int, j>();

Ni gcc ni clang compilan esto, porque j no es una "constante integral".