c++ - ternarios - Inicializando captura lambda en operador ternario.
operador ternario ejemplo c++ (3)
Cada expresión lambda tiene un tipo único (es decir, el tipo de cierre, que es un tipo de clase no agregada no agregada sin nombre único), incluso con la misma firma y cuerpo de función; el compilador simplemente no puede deducir el tipo común de operador condicional ternario para la variable declarada por auto
, los dos tipos de cierre son irrelevantes en absoluto.
Puedes usar std::function
lugar. p.ej
std::function<bool()> l1;
if (condition)
l1 = [](){ return true; };
else
l1 = [number](){ return number == 123; };
Para l4
, tenga en cuenta que la expresión lambda con la lista de captura vacía podría convertirse implícitamente en el puntero de la función correspondiente. En este caso, ambos podrían convertirse al mismo tipo de puntero de función (es decir, bool(*)(int)
), que luego podría deducirse como el tipo común de operador condicional ternario y el tipo de l4
.
Quería crear un lambda de la siguiente manera:
auto l1 = condition ?
[](){ return true; } :
[number](){ return number == 123; };
Sin embargo, tengo error:
operands to ?: have different types ‘main()::<lambda()>’ and ‘main()::<lambda()>’
Obviamente, los tipos parecen ser los mismos. Pensé que ese number
captura en solo una de las lambdas podría ser un problema, pero recibo el mismo error para estos:
//check if capturing number in both lambdas would help
auto l2 = condition ?
[number](){ return true; } :
[number](){ return number == 123; };
//maybe the first lambda capture was optimised out? let''s make sure:
auto l3 = condition ?
[number](){ return number != 123; } :
[number](){ return number == 123; };
Soy consciente de que puedo hacerlo de otra manera (a continuación), pero me pregunto cuál es la causa de este comportamiento. Se compiló con GCC6.3.1, C ++ 14 habilitado.
//compiles
auto l4 = condition ?
[](const int){ return true; } :
[](const int number){ return number == 123; };
Si realmente desea utilizar el operador condicional, puede hacerlo de la siguiente manera:
auto l1 = condition
? std::function<bool()>{[](){ return true; }}
: std::function<bool()>{[number](){ return number == 123; }};
En C ++ 17, esto se puede simplificar gracias a la deducción de argumentos de la plantilla de Clase :
auto l1 = condition
? std::function{[](){ return true; }}
: std::function{[number](){ return number == 123; }};
Un lambda en C ++ es una instancia de una clase local que implementa un contrato de funtor. Quiero decir, operador (), etc. Y estas clases no están relacionadas y tienen diferentes tipos.
Su código es equivalente a
struct l1 {
bool operator () const {
return true;
}
};
struct l2 {
private int number_:
l2(int number): number_(number){}
bool operator () const {
return number_ == 123;
}
};
int number = ???
auto l3 = condition ? l1 : l2(number);