Gostaria de saber se é possível escrever uma função que retorna uma função lambda em C ++ 11. Claro, um problema é como declarar tal função. Cada lambda tem um tipo, mas esse tipo não pode ser expresso em C ++. Eu não acho que isso funcionaria:
auto retFun() -> decltype ([](int x) -> int)
{
return [](int x) { return x; }
}
Nem este:
int(int) retFun();
Não estou ciente de nenhuma conversão automática de lambdas para, digamos, ponteiros para funções ou algo parecido. A única solução é criar um objeto de função manualmente e devolvê-lo?
decltype
não é o mesmo que no corpo da função e, portanto, tem um tipo diferente (mesmo se você incluiu a instrução return)decltype([](){})
orsizeof([]() {})
está malformado, não importa onde você o escreva.Respostas:
Você não precisa de um objeto de função artesanal, apenas use
std::function
, para o qual as funções lambda são conversíveis:Este exemplo retorna a função de identidade de inteiro:
fonte
std::function
.std::function
emprega apagamento de tipo, o que pode significar o custo de fazer uma chamada de função virtual ao chamar ostd::function
. Algo para estar ciente se a função retornada será usada em um loop interno restrito ou outro contexto em que a pequena ineficiência seja importante.Para este exemplo simples, você não precisa
std::function
.Do padrão §5.1.2 / 6:
Como sua função não tem uma captura, isso significa que o lambda pode ser convertido em um ponteiro para função do tipo
int (*)(int)
:Esse é o meu entendimento, corrija-me se eu estiver errado.
fonte
Você pode retornar a função lambda de outra função lambda, já que não deve especificar explicitamente o tipo de retorno da função lambda. Basta escrever algo assim em escopo global:
fonte
Embora a questão pergunte especificamente sobre C ++ 11, para o bem de outras pessoas que se deparam com isso e têm acesso a um compilador C ++ 14, C ++ 14 agora permite tipos de retorno deduzidos para funções comuns. Portanto, o exemplo em questão pode ser ajustado apenas para funcionar conforme desejado, simplesmente descartando a
-> decltype
cláusula ... após a lista de parâmetros de função:Observe, entretanto, que isso não funcionará se mais de um
return <lambda>;
aparecer na função. Isso ocorre porque uma restrição na dedução do tipo de retorno é que todas as instruções de retorno devem retornar expressões do mesmo tipo, mas cada objeto lambda recebe seu próprio tipo exclusivo pelo compilador, portantoreturn <lambda>;
, cada expressão terá um tipo diferente.fonte
auto retFun() { return [](auto const& x) { return x; }; }
Você deve escrever assim:
para obter seu retorno como uma função e usá-lo como:
fonte
Se você não tiver o c ++ 11 e estiver executando seu código c ++ em micro controladores, por exemplo. Você pode retornar um ponteiro vazio e, em seguida, executar uma conversão.
fonte