Como fazer com que as funções do C ++ 11 utilizem a função <> os parâmetros aceitam lambdas automaticamente

C ++ 11 tem lambda e std :: function <>, mas infelizmente, eles têm tipos diferentes. Uma conseqüência é que não se pode usar diretamente lambda em funções de ordem superior, como map in lisp. Por exemplo, no código a seguir

 #include <vector>
 #include <functional>
 using namespace std;

 template <typename A,typename B> 
 vector<B> map(std::function<B (A)> f, vector<A> arr) {
       vector<B> res;
       for (int i=0;i<arr.size();i++) res.push_back(f(arr[i]));
       return res;
}

int main () {
    vector<int> a = {1,2,3};
    map([](int x) -> int { return x;},a); //not OK

    auto id_l = [](int x) -> int { return x;};
    map(id_l,a); //not OK;

    function<int (int)> id_f = id_l;
    map(id_f,a); //OK
return 0;
}

, diretamente usando lambda como na linha 2 do main () não funcionará.g++ -std=c++11 testfunc.cpp devolve `... testfunc.cpp: 14: 37: note: 'main () :: __ lambda0' não é derivado de 'std :: function'.

A inferência do tipo C ++ 11 também falha, como você pode ver se um armazena o lambda em uma variável automática e depois o usa, as informações do tipo ainda são perdidas, provavelmente devido ao apagamento do tipo e motivos de pequena penalidade de desempenho contou:Por que as funções lambda em c ++ 11 não possuem tipos function <>?).

O que funciona é armazenar o lambda em uma variável std: function <> e usar essa variável. Isso é bastante inconveniente e meio que anula o propósito de usar o lambda na programação funcional em C ++ 11. Por exemplo, não se pode manipular lambda's com coisas como bind ou flip, e em vez disso, armazenar o lambda em uma variável primeiro.

Minha pergunta é, é possível (e como) superar esse problema e tornar a linha # 2 de main () legal, por exemplo, sobrescrevendo alguns operadores de typecast? (Claro, isso significa que eu não me importo com a pequena penalidade de desempenho envolvida em usar / não usar o tipo de apagamento).

desde já, obrigado.

--- EDIT ---

Para esclarecer, a razão pela qual eu usostd::function em vez de um parâmetro de tipo genérico para o parâmetro funcional é questd::function tem informações de tipo exatas, enquanto um parâmetro de tipo genérico como emtemplate <typename F> map(F f, ...) não contém informações de tipo. Além disso, como eu finalmente descobri, cada lambda é seu próprio tipo. Então, o apagamento do tipo não foi nem um problema na incompatibilidade entre um lambda e sua correspondênciastd::function objeto.

---Atualizar---

Já existem duas respostas sobre como tornar a função do mapa acima do trabalho ou como melhorá-las. Só para esclarecer. Minha pergunta não é sobre como fazer o mapa funcionar. Existem muitos outros casos de uso envolvendo o uso dos parâmetros std :: function <>, o que eu acho que pode pelo menos tornar o código mais legível e facilitar a inferência de tipos. As respostas até agora são sobre como não usar std :: function <> como parâmetros. Minha pergunta foi sobre como fazer tal função (com std :: function <> parâmetros digitados) aceitar lambda automaticamente.

- Atualização 2 ---

Em resposta aos comentários, aqui está um exemplo de caso prático em que as informações de tipo em std :: function <> COULD são úteis. Suponha que queremos implementar um equivalente em C ++fold_right : ('a -> 'b -> 'b) -> 'a list -> 'b -> 'b em OCaml (http://caml.inria.fr/pub/docs/manual-ocaml/libref/List.html).

Com std :: function <>, pode-se fazer

 //approach#1
 template <typename A,typename B> 
 B fold_right(std::function<B (A, B)> f, vector<A> arr, B b) {
     ...
 }

É claro de cima o quef é, e o que pode ou não pode tomar. Talvez, também se possa usar

 //approach#2
 template <typename A,typename B, typename F> 
 auto fold_right2(F f, vector<A> arr, B b) -> decltype(f(???)) {
      ...
 }

Mas, isso está ficando meio feio quando você tenta descobrir o que colocar nodecltype. Além disso, o que exatamentef tomar e qual é a maneira correta de usarf? Do ponto de vista da legibilidade, acho que o leitor do código só pode descobrir o que é f (uma função ou escalar) e a assinatura de f INTERPRETANDO a implementação no corpo da função.

Isso é o que eu não gosto e é daí que vem minha pergunta. Como fazer a abordagem 1 funcionar convenientemente. Por exemplo, sef representa adição de dois números, a abordagem # 1 funciona se você criar um objeto de função primeiro:

std::function<int (int, int)> add = [](int x, int y) -> int { return x + y; }
fold_right(add,{1,2,3},0);

Questões de eficiência à parte, o código acima é inconveniente, porque std :: function não pode aceitar lambda. Assim,

fold_right([](int x, int y) -> int { return x + y; },{1,2,3},0);

não funcionará atualmente no C ++ 11. Minha pergunta é especificamente sobre se é possível fazer funções comofold_right definido acima aceita lambda's diretamente. Talvez seja demais esperar. Espero que isso esclarece a questão.

questionAnswers(5)

yourAnswerToTheQuestion