Skip to content

is_pointer_interconvertible_base_of_v<B, D> が真となる理由の説明見直し #824

Description

@k-satoda

@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 として挙げさせてもらいます。意見・修正案などもらえると助かります。

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions