のは、私はこれらの型を持っているとしましょう:ポインタキャストが簡単であるという静的アサートを行うにはどうすればよいですか?
struct A {
int a;
};
struct B {
int b;
};
struct C : public A, public B {
int c;
};
C*
ポインタは全く実際のアドレスを調整せずA*
ポインタにキャストすることができます。しかしC*
がB*
にキャストされている場合は、値を変更する必要があります。私が持っている2つの関連する型を、アドレスの変更なしに(つまり、多重継承がない、または基底クラスが派生クラスの最初の基底である)互いにキャストできることを確認したい。これは実行時にチェックすることができます。ように
assert(size_t(static_cast<A*>((C*)0xF000) == 0xF000);
assert(size_t(static_cast<B*>((C*)0xF000) != 0xF000);
それは動作します。しかし、この情報はコンパイル時に知られているので、コンパイル時のアサーションを行う方法を探しています。上記を静的なアサーションに変換する明白な方法(たとえば、assert
をBOOST_STATIC_ASSERT
に置き換えることは、g ++ 4.2で "整数型または列挙型以外の型へのキャストは定数式に現れません"というエラーを出す)
移植性あまり重要ではありませんgccの拡張機能、またはハックテンプレートのトリックを使用して、すべての罰金となり
更新:。。は、ほぼ同じ質問をする前に頼まれたことが判明:。C++, statically detect base classes with differing addresses?offsetof()
を使用してもそこだけ便利な提案です。
ニックピッチになりたくはありませんが、正確なメモリレイアウトは実装の詳細なので...なぜこの点に正確に興味がありますか? –
私はBoost/lambdaライブラリにこれのためのものが含まれていると確信しています。私はそれを見なければならないだろうが、AlexandrescuとVandervoordeはこの分野のあらゆるトリックを公表している。 – sehe
@Matthieu M.が提示している質問に本当に興味がある:キャストが簡単なことがあればどんな状況が重要か? (つまり、それが自明でない場合、コストはほとんど無視できる:導出されたポインタに定数を加え、条件が適切に実行されないと、壊れたメモリのようなものをデバッグしようとすると本当の苦痛にぶつかる) –