functional expresiones examples cppreference cplusplus c++ c++11 lambda typetraits

c++ - expresiones - ¿Cuándo es un lambda trivial?



std c++ (2)

De acuerdo con el borrador de la norma N4527 5.1.2 / 3 expresiones Lambda [expr.prim.lambda] ( énfasis mío ):

El tipo de expresión lambda (que también es el tipo de objeto de cierre) es un tipo de clase no sindical sin nombre único, denominado tipo de cierre, cuyas propiedades se describen a continuación. Este tipo de clase no es un agregado (8.5.1) ni un tipo literal (3.9). El tipo de cierre se declara en el ámbito de bloque más pequeño, alcance de clase o ámbito de espacio de nombres que contiene la expresión lambda correspondiente. [Nota: Esto determina el conjunto de espacios de nombres y clases asociados con el tipo de cierre (3.4.2). Los tipos de parámetros de un lambdadeclarator no afectan estos espacios de nombres y clases asociados. - nota final] Una implementación puede definir el tipo de cierre de manera diferente a la que se describe a continuación, siempre que esto no altere el comportamiento observable del programa que no sea el cambio:

(3.1) - el tamaño y / o la alineación del tipo de cierre,

(3.2) - si el tipo de cierre es trivialmente copiable (Cláusula 9),

(3.3) - si el tipo de cierre es una clase de diseño estándar (Cláusula 9), o

(3.4) - si el tipo de cierre es una clase POD (Cláusula 9).

Una implementación no debe agregar miembros del tipo de referencia rvalue al tipo de cierre

Por lo tanto, depende de la implementación.

¿Cuándo se garantiza que una lambda será trivial, si es que alguna vez?

Supuse que si captura solo tipos triviales o nada, sería trivial. No tengo ningún estándar-ese para respaldar eso.

Mi motivación fue mover algún código de Visual C ++ 12 a 14 y descubrí que algunas afirmaciones estáticas fallaron cuando se trataba de lambdas que asumí que eran triviales.

Ejemplo:

#include <type_traits> #include <iostream> using namespace std; int main() { auto lambda = [](){}; cout << boolalpha << is_trivially_copyable<decltype(lambda)>{} << endl; }

Esto produce false en vs140 pero true en vs120 y clang. No pude probar gcc por no tener gcc> = 5. Espero que esto sea una regresión en el vs140, pero no estoy seguro del comportamiento correcto aquí.


El estándar no especifica si un tipo de cierre (el tipo de una expresión lambda) es trivial o no. Esto explícitamente deja esto a la implementación, lo que lo hace no portátil. Me temo que no puede confiar en su static_assert produciendo algo consistente.

Citando a C ++ 14 (N4140) 5.1.2 / 3:

... Una implementación puede definir el tipo de cierre de forma diferente a la que se describe a continuación, siempre que esto no altere el comportamiento observable del programa que no sea el cambio:

  • el tamaño y / o la alineación del tipo de cierre,
  • si el tipo de cierre es trivialmente copiable (Cláusula 9),
  • si el tipo de cierre es una clase de diseño estándar (Cláusula 9), o
  • si el tipo de cierre es una clase POD (Cláusula 9).

...

(Énfasis mío)

Después de analizar la doble negación en esa oración, podemos ver que la implementación puede decidir si el tipo de cierre es trivialmente copiable, diseño estándar o POD.