void* とメンバー関数へのポインター間のキャスト
C プログラミングの世界では、void* とメンバー関数へのポインター間のキャストメンバー関数は本当に頭の痛い問題になる可能性があります。この課題を説明する具体的な問題を見てみましょう。
次のコード スニペットを考えてみましょう:
<code class="cpp">template <class T> int call_int_function(lua_State *L) { void (T::*method)(int, int) = reinterpret_cast<void (T::*)(int, int)>(lua_touserdata(L, lua_upvalueindex(1))); // <-- problematic line T *obj = reinterpret_cast<T *>(lua_touserdata(L, 1)); (obj->*method)(lua_tointeger(L, 2), lua_tointeger(L, 3)); return 0; }</code>
ここで、GCC は void* から void (T::*) へのキャストが不平を言っています。 (int, int) は無効です。では、解決策は何でしょうか?
問題の理解
問題を理解するには、メンバー関数へのポインターの性質をさらに深く掘り下げる必要があります。アドレスを指す通常のポインターとは異なり、メンバー関数へのポインターははるかに複雑です。これらには、コンパイラの実装とクラス メンバーのレイアウトに固有の情報が含まれています。
代替アプローチ
実際には、 void* をポインタに直接キャストすることはできません。メンバー関数に。提案される解決策には、メンバー関数を通常の関数でラップし、代わりにそれを返すことが含まれます。その方法は次のとおりです。
<code class="cpp">template <class T> int call_int_function(lua_State *L) { void (*method)(T*, int, int) = reinterpret_cast<void (*)(T*, int, int)>(lua_touserdata(L, lua_upvalueindex(1))); T *obj = reinterpret_cast<T *>(lua_touserdata(L, 1)); method(obj, lua_tointeger(L, 2), lua_tointeger(L, 3)); return 0; }</code>
このアプローチは、現在、通常の関数ポインターにキャストしているため機能します。これは void* に格納でき、問題なく取得できます。
以上がC で `void*` とメンバー関数へのポインタの間で安全にキャストする方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。