以下は、C++ 11にのみ役立つ何かを行う際の、徹底的にテストされていない試みです(実際にはは実際にはにはC++ 11の機能が必要ですが、
しかし、この特性は唯一のプロパティ「の主な基底クラスである」の推移閉包チェック:私はクラスが別の直接基底クラスであるかどうかを検証する非侵入的な方法を見つけ出すことができませんでしたがクラス。ここで
#include <type_traits>
template<typename B, typename D, D* p = nullptr, typename = void>
struct is_primary_base_of : std::false_type { };
template<typename B, typename D, D* p>
struct is_primary_base_of<B, D, p,
typename std::enable_if<
((int)(p + 1024) - (int)static_cast<B*>(p + 1024)) == 0
>::type
>
:
std::true_type { };
は一例です:
struct A { virtual ~A() { } };
struct B : A { };
struct C { virtual ~C() { } };
struct D : B, C { };
struct E : virtual A, C { };
int main()
{
// Does not fire (A is PBC of B, which is PBC of D)
static_assert(is_primary_base_of<A, D>::value, "Error!");
// Does not fire (B is PBC of C)
static_assert(is_primary_base_of<B, D>::value, "Error!");
// Fires (C is not PBC of D)
static_assert(is_primary_base_of<C, D>::value, "Error!");
// Fires (A is inherited virtually by E, so it is not PBC of E)
static_assert(is_primary_base_of<A, E>::value, "Error!");
// Does not fire (C is the first non-virtual base class of E)
static_assert(is_primary_base_of<C, E>::value, "Error!");
}
あなたのテスト式は全く引用された定義と一致しません。基本サブオブジェクトのアドレスを調べていますが、ABIはvテーブル内のエントリの順序について議論しています。 –
@BenVoigt:きれいに見つかった。 ABIへのリンクが本当にあるはずです。 –
私はこの情報を使用することができたのは非常に不思議です。 –