2011-12-12 15 views
5

Supongamos que tengo un tipo my_struct que incluye una variable miembro, f, que es una función. Es posible que f sea una función C++ 11 lambda.¿Cómo detectar si un tipo es una expresión lambda en el momento de la compilación?

Dado que es ilegal asignar objetos lambda, me gustaría implementar el operador de asignación my_struct de tal forma que cuando f es un lambda, no se asigne.

¿Es posible construir un tipo de rasgo is_lambda que pueda inspeccionar un tipo de lambda-ness?

En código:

#include <type_traits> 

template<typename Function> struct is_lambda 
{ 
    // what goes here? 
}; 

template<typename Function> struct my_struct 
{ 
    Function f; 

    my_struct &do_assign(const my_struct &other, std::true_type) 
    { 
    // don't assign to f 
    return *this; 
    } 

    my_struct &do_assign(const my_struct &other, std::false_type) 
    { 
    // do assign to f 
    f = other.f; 
    return *this; 
    } 

    my_struct &operator=(const my_struct &other) 
    { 
    return do_assign(other, typename is_lambda<Function>::type()); 
    } 
}; 

Respuesta

7

imposible sin el apoyo del compilador, como el tipo de un lambda es sólo un tipo de clase normal, no unión.

§5.1.2 [expr.prim.lambda] p3

El tipo de la lambda-expresión (que también es el tipo del objeto de cierre) es un, sin nombre tipo de clase seudoartrosis único [...]

4

Presumiblemente, tampoco desea asignar funciones no lambda no asignables, por lo que podría usar std::is_assignable.

+0

Esto parece funcionar en Visual C++ 2015, tal vez en versiones anteriores también. Usando simplemente: 'std :: is_assignable :: value'. Utilicé este método para asegurar que no se derivara una lambda cuando se usa _EBO_. –

+0

@MatthewHolder Sin embargo, ese no es el sentido de mi respuesta, que es que no debes tratar de darle a lambdas un trato especial. No hay nada inherentemente malo en derivar de un lambda. Tiene algunos aspectos que pueden hacer que sea complicado, pero esos mismos aspectos pueden aplicarse a las clases que no son lambda. El hecho de que no sean asignables no es uno de ellos, por lo que en su caso, creo que ese no es el aspecto que debe verificarse. – hvd

+0

Comprensible, pero una situación que requería que detectara una lambda era cuando pasaba un FunctionObject a un argumento de tipo de plantilla de clase que se utilizará como la clase base de la plantilla de clase para Empty Base Optimization. Dado que no puede heredar un tipo lambda en ciertas situaciones o en ciertos compiladores. A medida que mejore esta situación ... eso ya no será un problema. –

Cuestiones relacionadas