namespace std {
template <class Base, class Derived>
struct is_pointer_interconvertible_base_of;
template<class Base, class Derived>
inline constexpr bool is_pointer_interconvertible_base_of_v
= is_pointer_interconvertible_base_of<Base, Derived>::value;
}
概要
基底クラスBaseと派生クラスDerivedの間でポインタ相互交換可能かを判定する。
要件
BaseとDerivedが非共用体のクラスであり、異なる型である場合(cv修飾は無視される)、Derivedは完全型でなければならない。
効果
is_pointer_interconvertible_base_ofは、(cv修飾を無視して)DerivedがBaseから曖昧さなく派生しかつ型DerivedのオブジェクトがBaseサブオブジェクトとポインタ相互交換可能(pointer-interconvertible)である、もしくはBaseとDerivedが非共用体の(cv修飾を無視した)同一クラス型を指すならばtrue_typeから派生し、そうでなければfalse_typeから派生する。
2つオブジェクトa, bが下記条件のいずれかを満たすとき、ポインタ相互交換可能(pointer-interconvertible)である。
- 両者が同一オブジェクトである。
- 一方が共用体オブジェクトであり、他方が共用体オブジェクトの非静的メンバ変数である。
- 一方がスタンダードレイアウトクラスオブジェクトであり他方が同オブジェクトの先頭の非静的メンバ変数、または同オブジェクトが非静的メンバ変数を持たなければ同オブジェクトの基底クラスサブオブジェクトである。
aとポインタ相互交換可能(pointer-interconvertible)なオブジェクトcが存在し、cとbがポインタ相互交換可能(pointer-interconvertible)である。
2つのオブジェクトがポインタ相互交換可能(pointer-interconvertible)であれば、両者は同一のアドレス値を持ち、reinterpret_castによって一方から他方のポインタへ変換可能である。(配列オブジェクトとその先頭要素は、同一のアドレスを持つにもかかわらずポインタ相互交換可能(pointer-interconvertible)ではない。)
例
#include <type_traits>
struct B { int m; };
struct D : B {};
int main()
{
// スタンダードレイアウト派生クラスDは非静的メンバ変数をもたず、
// スタンダードレイアウト基底クラスBから曖昧さなく派生しているため、
// 基底クラスBと派生クラスDはポインタ相互交換可能である。
static_assert(std::is_pointer_interconvertible_base_of_v<B, D>);
// 同一クラス同士は(自明に)ポインタ相互交換可能である。
static_assert(std::is_pointer_interconvertible_base_of_v<D, D>);
}
出力
バージョン
言語
- C++20
処理系
- Clang: ??
- GCC: ??
- Visual C++: ??