Por que as funções lambda em c ++ 11 não possuem tipos function <>?
Estou brincando com os recursos funcionais do c ++ 11. Uma coisa que acho estranho é que o tipo de uma função lambda não é na verdade uma função <>. Além disso, os lambda não parecem tocar muito bem com o mecanismo de inferência de tipos.
Anexado é um pequeno exemplo no qual testei invertendo os dois argumentos de uma função para adicionar dois inteiros. (O compilador que usei foi gcc 4.6.2 em MinGW.) No exemplo, o tipo paraaddInt_f
foi explicitamente definida usando a função <>addInt_l
é um lambda cujo tipo é inferido por tipo comauto
.
Quando eu compilei o código, oflip
função pode aceitar a versão explicitamente definida pelo tipo de addInt, mas não a versão lambda, dando um erro dizendo que,testCppBind.cpp:15:27: error: no matching function for call to 'flip(<lambda(int, int)>&)'
As próximas linhas mostram que a versão lambda (assim como uma versão 'bruta') pode ser aceita se for explicitamente convertida para a função apropriada <> type.
Então minhas perguntas são:
Por que é que uma função lambda não tem umfunction<>
digite o primeiro lugar? No pequeno exemplo, por que nãoaddInt_l
terfunction<int (int,int)>
como o tipo em vez de ter um diferente,lambda
tipo? Do ponto de vista da programação funcional, qual é a diferença entre um objeto funcional / funcional e um lambda?
Se há uma razão fundamental para que esses dois sejam diferentes. Ouvi dizer que os lambda's podem ser convertidos emfunction<>
mas eles são diferentes. Esta é uma questão de design / defeito do C ++ 11, uma questão de implementação ou existe um benefício em distinguir os dois da maneira que é? Parece que a assinatura do tipo deaddInt_l
sozinho forneceu informações suficientes sobre o parâmetro e os tipos de retorno da função.
Existe uma maneira de escrever o lambda para que o vazamento explícito mencionado acima possa ser evitado?
Desde já, obrigado.
//-- testCppBind.cpp --
#include <functional>
using namespace std;
using namespace std::placeholders;
template <typename T1,typename T2, typename T3>
function<T3 (T2, T1)> flip(function<T3 (T1, T2)> f) { return bind(f,_2,_1);}
function<int (int,int)> addInt_f = [](int a,int b) -> int { return a + b;};
auto addInt_l = [](int a,int b) -> int { return a + b;};
int addInt0(int a, int b) { return a+b;}
int main() {
auto ff = flip(addInt_f); //ok
auto ff1 = flip(addInt_l); //not ok
auto ff2 = flip((function<int (int,int)>)addInt_l); //ok
auto ff3 = flip((function<int (int,int)>)addInt0); //ok
return 0;
}