Eu tinha uma percepção de que o tipo de lambda é um ponteiro de função. Quando realizei o seguinte teste, achei errado ( demo ).
#define LAMBDA [] (int i) -> long { return 0; }
int main ()
{
long (*pFptr)(int) = LAMBDA; // ok
auto pAuto = LAMBDA; // ok
assert(typeid(pFptr) == typeid(pAuto)); // assertion fails !
}
O código acima está faltando algum ponto? Caso contrário, qual é a typeof
expressão a lambda quando deduzida com a auto
palavra - chave?
Respostas:
O tipo de uma expressão lambda não é especificado.
Mas eles geralmente são mero açúcar sintático para functores. Um lambda é traduzido diretamente em um functor. Qualquer coisa dentro do
[]
é transformada em parâmetros do construtor e membros do objeto functor, e os parâmetros dentro()
são transformados em parâmetros para o functoroperator()
.Um lambda que captura nenhuma variável (nada dentro
[]
dos) pode ser convertido em um ponteiro de função (o MSVC2010 não suporta isso, se esse é o seu compilador, mas essa conversão faz parte do padrão).Mas o tipo real do lambda não é um ponteiro de função. É algum tipo de functor não especificado.
fonte
operator()
basicamente stackoverflow.com/questions/356950/c-functors-and-their-usesÉ uma estrutura única e sem nome que sobrecarrega o operador de chamada de função. Toda instância de um lambda apresenta um novo tipo.
No caso especial de um lambda que não captura, a estrutura além disso tem uma conversão implícita em um ponteiro de função.
fonte
type_info::name()
é definido pela implementação, portanto, ele pode retornar qualquer coisa. Na prática, o compilador nomeará o tipo em nome do vinculador.A cláusula continua listando propriedades variadas desse tipo. Aqui estão alguns destaques:
A consequência desta passagem final é que, se você usasse uma conversão, seria capaz de atribuir
LAMBDA
apFptr
.fonte
Os tipos de função são realmente os mesmos, mas o lambda apresenta um novo tipo (como um functor).
fonte
__PRETTY_FUNCTION__
, como dentrotemplate<class T> const char* pretty(T && t) { return __PRETTY_FUNCTION__; }
, e retirar o extra se ele começar a ficar lotado. Prefiro ver as etapas mostradas na substituição de modelo. Se estiver faltando__PRETTY_FUNCTION__
, existem alternativas para o MSVC etc., mas os resultados sempre dependem do compilador pelo mesmo motivo que o CXXABI é necessário.Observe também que lambda é conversível em ponteiro de função. No entanto, typeid <> retorna um objeto não trvial que deve diferir de lambda para ponteiro de função genérica. Portanto, o teste para typeid <> não é uma suposição válida. Em geral, o C ++ 11 não quer que nos preocupemos com a especificação de tipo, tudo isso importa se um determinado tipo é conversível em um tipo de destino.
fonte
Uma solução prática de Como posso armazenar um objeto boost :: bind como um membro da classe? , tente
boost::function<void(int)>
oustd::function<void(int)>
.fonte