異なる署名を持つ関数へのポインターを格納したい場合、それらをvoid(*)()
(または他の関数ポインター型に) キャストしてから、呼び出す前に元の型にキャストし直すことができます。しかし、メンバー関数ポインターはどうでしょうか? メンバー関数ポインターを別の型 (おそらく異なるクラスのメンバー関数) の別のメンバー関数ポインターを介してラウンドトリップしても、何かが壊れないという保証はありますか?
2 に答える
はい、reinterpret_cast
両方のケースでデータメンバーへのポインターまたはメンバー関数へのポインターを維持する限り、メンバーへのポインター型間のラウンドトリップは有効であることが保証されます。
C++11 の引用:
[expr.reinterpret.cast]
10 型「型のメンバへのポインタ」の prvalue は、とが両方とも関数型または両方のオブジェクト型である場合、別の
X
型「型のT1
メンバへのポインタ」の prvalue に明示的に変換できます。null メンバー ポインター値 (4.11) は、変換先の型の null メンバー ポインター値に変換されます。次の場合を除いて、この変換の結果は規定されていません。Y
T2
T1
T2
- 「メンバー関数へのポインター」型の prvalue をメンバー関数型への別のポインターに変換し、元の型に戻すと、メンバー値への元のポインターが生成されます。
私はそう思いますreinterptret_cast
。それが標準の言うことです(5.2.11/10)
T1 と T2 が両方とも関数型または両方のオブジェクト型である場合、型「T1 型の X のメンバーへのポインター」の prvalue は、別の型「T2 型の Y のメンバーへのポインター」の prvalue に明示的に変換できます。 null メンバー ポインター値 (4.11) は、変換先の型の null メンバー ポインター値に変換されます。次の場合を除いて、この変換の結果は規定されていません。
— 「メンバー関数へのポインター」型の prvalue をメンバー関数型への別のポインターに変換し、元の型に戻すと、メンバー値への元のポインターが生成されます。
— 「T1 型の X のデータ メンバーへのポインター」型の prvalue を「T2 型の Y のデータ メンバーへのポインター」型 (T2 のアラインメント要件は T1 のアラインメント要件より厳密ではない) に変換し、元の値に戻す元の型は、メンバー値への元のポインターを生成します。