Estou tentando descobrir como obter o endereço de uma função lambda dentro de si. Aqui está um código de exemplo:
[]() {
std::cout << "Address of this lambda function is => " << ????
}();
Eu sei que posso capturar o lambda em uma variável e imprimir o endereço, mas quero fazê-lo no lugar quando esta função anônima estiver em execução.
Existe uma maneira mais simples de fazer isso?
this
.Respostas:
Não é diretamente possível.
No entanto, capturas lambda são classes e o endereço de um objeto coincide com o endereço de seu primeiro membro. Portanto, se você capturar um objeto por valor como a primeira captura, o endereço da primeira captura corresponde ao endereço do objeto lambda:
Saídas:
Como alternativa, você pode criar um padrão de design decorador lambda que transmita a referência para a captura lambda em seu operador de chamada:
fonte
Não há como obter diretamente o endereço de um objeto lambda dentro de um lambda.
Agora, como acontece, isso geralmente é útil. O uso mais comum é para se recuperar.
Ele
y_combinator
vem de idiomas em que você não poderia falar sobre si mesmo até onde foi definido. Ele pode ser implementado facilmente no c ++ :agora você pode fazer isso:
Uma variação disso pode incluir:
onde o
self
passado pode ser chamado sem passarself
como o primeiro argumento.O segundo corresponde ao combinador real y (também conhecido como combinador de ponto fixo), acredito. O que você deseja depende do que você quer dizer com 'endereço de lambda'.
fonte
F
layout não é padrão,y_combinator
não é, portanto as garantias sensatas não são fornecidas.Uma maneira de resolver isso seria substituir o lambda por uma classe functor escrita à mão. É também o que o lambda está essencialmente sob o capô.
Então você pode obter o endereço
this
, mesmo sem nunca atribuir o functor a uma variável:Isso tem a vantagem de ser 100% portátil e extremamente fácil de raciocinar e entender.
fonte
struct { void operator()() { std::cout << "Address of this functor is => " << this << '\n'; } } f;
Capture a lambda:
fonte
std::function
não é necessária aqui, porém, e tem um custo considerável. Além disso, copiar / mover esse objeto irá quebrá-lo.É possível, mas depende muito da otimização da plataforma e do compilador.
Na maioria das arquiteturas que conheço, existe um registro chamado ponteiro de instruções. O objetivo desta solução é extraí-la quando estivermos dentro da função.
Em amd64, o código a seguir deve fornecer endereços próximos à função
Mas, por exemplo, no gcc https://godbolt.org/z/dQXmHm com a
-O3
função de nível de otimização pode estar embutido.fonte
thread_local
duração automática ou de armazenamento. O que você está tentando obter aqui é o endereço de retorno da função, não um objeto. Mas mesmo isso não funcionará porque o prólogo da função gerada pelo compilador envia para a pilha e ajusta o ponteiro da pilha para liberar espaço para variáveis locais.