¿Cuándo es un lambda trivial?


¿Cuándo se garantiza que un lambda a sea trivial, si es que lo es?

Asumí que si captura solo tipos triviales o nada, sería trivial. Sin embargo, no tengo ningún estándar para respaldar eso.

Mi motivación estaba en mover algo de código de Visual C++ 12 a 14 y descubrí que algunas afirmaciones estáticas fallaban al tratar con 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 debido a no tener gcc > = 5 alrededor. Espero que esto sea una regresión en vs140, pero no estoy seguro del comportamiento correcto aquí.

Author: tahsmith, 2015-10-07

2 answers

El estándar no especifica si un tipo de cierre (el tipo de una expresión lambda) es trivial o no. Deja esto explícitamente en manos de la implementación, lo que lo hace no portable. Me temo que no puede confiar en su static_assert producir nada consistente.

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

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

  • 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 decida si el tipo de cierre se puede copiar trivialmente, diseño estándar o POD.

Tenga en cuenta que la misma redacción también está presente en C++17 (N4659), [expr.prim.lambda.cierre] 8.1.5.1/2.

 31
Author: Angew,
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
2018-08-20 08:17:02

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

El tipo de la expresión lambda (que también es el tipo de closure object) es un tipo de clase no unido único, sin nombre, llamado 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). Cierre el tipo se declara en el ámbito de bloque más pequeño, ámbito 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 asociadas con el tipo de cierre (3.4.2). Los tipos de parámetros de un lambdadeclarator no afecta a estos espacios de nombres asociados y clase. - end note] Una implementación puede definir el tipo de cierre a diferencia de lo que se describe a continuación, siempre que esto no altere el comportamiento observable del programa que no sea cambiando:

(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 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 aplicación deberá no añadir miembros del tipo de referencia rvalue al tipo de cierre

Por lo tanto, depende de la implementación.

 14
Author: 101010,
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
2016-08-25 11:21:32