tutorial sintaxis expresiones español c++ templates c++11 lambda

c++ - sintaxis - ¿Cómo usar una expresión lambda como un parámetro de plantilla?



lambda sintaxis (4)

El segundo parámetro de plantilla de std::set espera un tipo , no una expresión , por lo que solo lo está utilizando incorrectamente.

Podrías crear el conjunto así:

auto comp = [](const A& lhs, const A& rhs) -> bool { return lhs.x < rhs.x; }; auto SetOfA = std::set <A, decltype(comp)> (comp);

¿Cómo usar la expresión lambda como un parámetro de plantilla? Por ejemplo, como una clase de comparación que inicializa un std :: set.

La siguiente solución debería funcionar, ya que la expresión lambda simplemente crea una estructura anónima, que debería ser apropiada como un parámetro de plantilla. Sin embargo, se generan muchos errores.

Ejemplo de código:

struct A {int x; int y;}; std::set <A, [](const A lhs, const A &rhs) ->bool { return lhs.x < rhs.x; } > SetOfA;

Salida de error (estoy usando el compilador g ++ 4.5.1 y --std = indicador de compilación c ++ 0x):

error: ‘lhs’ cannot appear in a constant-expression error: ‘.’ cannot appear in a constant-expression error: ‘rhs’ cannot appear in a constant-expression error: ‘.’ cannot appear in a constant-expression At global scope: error: template argument 2 is invalid

¿Es ese el comportamiento esperado o un error en GCC?

EDITAR

Como alguien señaló, estoy usando expresiones lambda incorrectamente ya que devuelven una instancia de la estructura anónima a la que se refieren.

Sin embargo, corregir ese error no resuelve el problema. Obtengo lambda-expression in unevaluated context error de lambda-expression in unevaluated context para el siguiente código:

struct A {int x; int y;}; typedef decltype ([](const A lhs, const A &rhs) ->bool { return lhs.x < rhs.x; }) Comp; std::set <A, Comp > SetOfA;


No estoy seguro de si esto es lo que está preguntando, pero la firma de un lambda que devuelve RetType y acepta InType será:

std::function<RetType(InType)>

(Asegúrese de #include <functional> )

Puede acortar eso usando un typedef, pero no estoy seguro de que pueda usar decltype para evitar averiguar el tipo real (ya que lambdas aparentemente no se puede usar en ese contexto).

Entonces tu typedef debería ser:

typedef std::function<bool(const A &lhs, const A &rhs)> Comp

o

using Comp = std::function<bool(const A &lhs, const A &rhs)>;


Para los comparadores usados ​​de esta manera, aún está mejor con un enfoque que no sea 0x:

struct A { int x; int y; }; struct cmp_by_x { bool operator()(A const &a, A const &b) { return a.x < b.x; } }; std::set<A, cmp_by_x> set_of_a;

Sin embargo, en 0x puede hacer de cmp_by_x un tipo local (es decir, definirlo dentro de una función) cuando sea más conveniente, lo cual está prohibido por el C ++ actual.

Además, su comparación trata A (x = 1, y = 1) y A (x = 1, y = 2) como equivalentes. Si eso no se desea, debe incluir los otros valores que contribuyen a la singularidad:

struct cmp_by_x { bool operator()(A const &a, A const &b) { return a.x < b.x || (a.x == b.x && a.y < b.y); } };


el problema es que el último parámetro de plantilla es escribir, no un objeto, por lo que es posible que desee hacer lo siguiente

std::set <A, std::fuction<bool(const A &,const A &)>> SetOfA([](const A lhs, const A &rhs) ->bool { return lhs.x < rhs.x; } > SetOfA;

para hacerlo más simple, puedes hacer lo siguiente:

auto func = SetOfA([](const A lhs, const A &rhs) ->bool { return lhs.x < rhs.x;} set <A,decltype(func)> SetOfA(func);

aclamaciones