関数へのポインターはvoid *ポインターに格納できないため、単純なデータポインターではありません。それにもかかわらず、以下のコードのように、関数ポインターのコピーを動的メモリ(gccとclang内)に保存できるようです。そのようなコードはC ++標準に従って合法ですか、またはこれはある種のコンパイラ拡張ですか?
さらに、結果の関数ポインターへのポインターはプレーンデータポインターとして動作します。私はそれをvoid *に格納し、static_castによってvoid *から取得できます。この動作は規格によって保証されていますか?
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 ;
}
newにキャストする必要はありませんvoid*。は関数ではなくオブジェクトなvoid* ptr = &fcnPtr;ので、同様にfcnPtr機能します。
std::functionは、任意の呼び出し可能オブジェクトを格納するための型消去されたコンテナーであり、実際には関数ポインターの代わりではありません…
std::function。「ポリモーフィック」関数(つまり、一部のラムダの場合のように状態が含まれていても、適切なシグネチャを持つもの)を格納する機能は優れていますが、不要なオーバーヘッドも追加されます。関数へのポインタはPODです。A std::functionはありません。
void*でそれを指し示すことを求めているので、この質問の文脈ではstd::functionまさに彼らが探していたもののようです。SPDによる関数ポインタの一般的な却下は不健全であることに同意します。
std::function代わりに使用してください。