Ponteiros para funções não são ponteiros de dados simples, pois não podem ser armazenados em um ponteiro nulo *. No entanto, parece que eu posso armazenar a cópia de um ponteiro de função na memória dinâmica (no gcc e no clang) como no código abaixo. Esse código é legal de acordo com o padrão C ++, ou talvez seja algum tipo de extensão do compilador?
Além disso, o ponteiro resultante para o ponteiro de função se comporta como um ponteiro simples de dados: eu posso armazená-lo no vácuo * e recuperá-lo do vácuo * pelo static_cast. Esse comportamento é garantido pelo Padrão?
int main()
{
extern void fcn();
void (*fcnPtr)() = &fcn;
void (**ptrToFcnPtr)() = nullptr;
//Make the copy of fcnPtr on the heap:
ptrToFcnPtr = new decltype(fcnPtr)(fcnPtr);
//Call the pointed-to function :
(**ptrToFcnPtr)();
//Save the pointer in void* :
void *ptr = ptrToFcnPtr;
//retrieve the original ptr:
auto myPtr = static_cast< void(**)() > (ptr) ;
//free memory:
delete ptrToFcnPtr ;
}
std::function
vez disso.new
elencovoid*
.void* ptr = &fcnPtr;
funciona tão bem, já quefcnPtr
é um objeto, não uma função.std::function
é um contêiner apagado por tipo para armazenar uma chamada arbitrária, não é realmente um substituto para ponteiros de função ...std::function
. É excelente por sua capacidade de armazenar funções "polimórficas" (ou seja, qualquer coisa com a assinatura correta, mesmo que contenha estado como no caso de algumas lambdas), mas isso também adiciona sobrecarga que pode não ser necessária. Um ponteiro para uma função é POD. Astd::function
não é.void*
, portanto, no contexto dessa pergunta,std::function
parece exatamente o que eles estavam procurando. Concordo que a dispensa geral dos indicadores de função do SPD não é doentia.Respostas:
Enquanto ponteiros de função não são ponteiros de objeto, "ponteiro para função de algum tipo" ainda é um tipo de objeto [basic.types] / 8 . Assim, os ponteiros de função são objetos em si, apenas o que eles apontam não é.
Assim, você pode criar um objeto do tipo ponteiro de função por meio de uma nova expressão…
fonte
Na verdade, o armazenamento de um ponteiro de função como a
void*
é suportado condicionalmente. Isso significa que ele pode ou não ser armazenado, dependendo da implementação do idioma. Se a implementação do idioma suportar carregamento dinâmico,void*
provavelmente a conversão do ponteiro de função é suportada. GCC, Clang e MSVC suportam isso:Certo. Todos os ponteiros, incluindo ponteiros de função, são objetos e todos os objetos podem ser alocados dinamicamente.
Ponteiro de função é um objeto. Ponteiro para um ponteiro de função não apenas "se comporta como", mas é um ponteiro para um objeto.
A conversão entre ponteiro para vazio e ponteiro para objeto é permitida, sim. E a conversão de ida e volta garante o ponteiro original.
fonte