@yohhoy (CC: @nilgawa) is_pointer_interconvertible_base_of.md より:
struct B { int m; };
struct D : B {};
int main()
{
// スタンダードレイアウト派生クラスDは非静的データメンバをもたず、
// スタンダードレイアウト基底クラスBから曖昧さなく派生しているため、
// 基底クラスBと派生クラスDはポインタ相互交換可能である。
static_assert(std::is_pointer_interconvertible_base_of_v<B, D>);
@yohhoy ここの「クラスDは非静的データメンバをもたず」は正しくないように思います。
https://timsong-cpp.github.io/cppwp/n4659/class.derived#2 より:
... Unless redeclared in the derived class, members of a base class are also considered to be members of the derived class. ...
↑によれば、 D は非静的データメンバ m を持つものとみなされます。
同記事内に挙げられたポインタ相互変換可能の条件「同オブジェクトが非静的データメンバを持たなければ同オブジェクトの基底クラスサブオブジェクト」が
仮に「同オブジェクトが直接のメンバ (direct member) として非静的データメンバを持たなければ~」という意味であるとすると、
以下のような場合に D2 に対して B2 もポインタ相互交換可能な基底クラスとなってしまいそうですが、 D2 と B2 とは同じアドレスに配置できないためそうはいきません。
struct B1 { int m; };
struct B2 {};
struct D2 : B1, B2 {};
記事中の D 型オブジェクトとその中の B 型の基底クラスサブオブジェクトとがポインタ相互交換可能となるのは、
それぞれが最初の非静的データメンバ m (に対応するメンバサブオブジェクト)とポインタ相互交換可能であるから、
ということになるかと思うんですが、・・・わかりやすい説明をひねり出すのがちょっと難しそうなので
一旦 issue として挙げさせてもらいます。意見・修正案などもらえると助かります。
@yohhoy (CC: @nilgawa) is_pointer_interconvertible_base_of.md より:
@yohhoy ここの「クラスDは非静的データメンバをもたず」は正しくないように思います。
https://timsong-cpp.github.io/cppwp/n4659/class.derived#2 より:
↑によれば、 D は非静的データメンバ m を持つものとみなされます。
同記事内に挙げられたポインタ相互変換可能の条件「同オブジェクトが非静的データメンバを持たなければ同オブジェクトの基底クラスサブオブジェクト」が
仮に「同オブジェクトが直接のメンバ (direct member) として非静的データメンバを持たなければ~」という意味であるとすると、
以下のような場合に D2 に対して B2 もポインタ相互交換可能な基底クラスとなってしまいそうですが、 D2 と B2 とは同じアドレスに配置できないためそうはいきません。
記事中の D 型オブジェクトとその中の B 型の基底クラスサブオブジェクトとがポインタ相互交換可能となるのは、
それぞれが最初の非静的データメンバ m (に対応するメンバサブオブジェクト)とポインタ相互交換可能であるから、
ということになるかと思うんですが、・・・わかりやすい説明をひねり出すのがちょっと難しそうなので
一旦 issue として挙げさせてもらいます。意見・修正案などもらえると助かります。