Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>There is no MRO in C++ like Python. If a method is ambiguous, it is a compile-time error. Whether a method is virtual or not doesn't affect it, but virtual <em>inheritance</em> will.</p> <hr> <p>The algorithm is described in the C++ standard &sect;[class.member.lookup] (10.2). Basically it will find the closest unambiguous implementation in the superclass graph. The algorithm works like this:</p> <ol> <li><p>Suppose you want to look up a function <strong>f</strong> in class <strong>C</strong>.</p></li> <li><p>We define a <em>look-up set</em> <strong>S(f, C)</strong> being a pair of sets (<strong>&Delta;</strong>, <strong>&Sigma;</strong>) representing all possibilities. <sub>(&sect;10.2/3)</sub></p> <ul> <li><p>The set <strong>&Delta;</strong> is called the <em>declaration set</em>, which is basically all the possible <strong>f</strong>'s.</p></li> <li><p>The set <strong>&Sigma;</strong> is called the <em>subobject set</em>, which contain the classes that these <strong>f</strong>'s are found.</p></li> </ul></li> <li><p>Let <strong>S(f, C)</strong> include all <strong>f</strong> directly defined (or <code>using</code>-ed) in <strong>C</strong>, if any <sub>(&sect;10.2/4)</sub>:</p> <pre><code>Δ = {f in C}; if (Δ != empty) Σ = {C}; else Σ = empty; S(f, C) = (Δ, Σ); </code></pre></li> <li><p>If <strong>S(f, C)</strong> is empty <sub>(&sect;10.2/5)</sub>, </p> <ul> <li><p>Compute <strong>S(f, B<sub>i</sub>)</strong> where <strong>B<sub>i</sub></strong> is a base class of <strong>C</strong>, for all <em>i</em>.</p></li> <li><p>Merge each <strong>S(f, B<sub>i</sub>)</strong> into <strong>S(f, C)</strong> one by one.</p> <pre><code>if (S(f, C) == (empty, empty)) { B = base classes of C; for (Bi in B) S(f, C) = S(f, C) .Merge. S(f, Bi); } </code></pre></li> </ul></li> <li><p>Finally the declaration set is returned as the result of name resolution <sub>(&sect;10.2/7)</sub>.</p> <pre><code>return S(f, C).Δ; </code></pre></li> <li><p>The merge between two look-up sets (<strong>&Delta;<sub>1</sub></strong>, <strong>&Sigma;<sub>1</sub></strong>) and (<strong>&Delta;<sub>2</sub></strong>, <strong>&Sigma;<sub>2</sub></strong>) is defined as <sub>(&sect;10.2/6)</sub>:</p> <ul> <li>If every class in <strong>Σ<sub>1</sub></strong> is a base class of at least one class in <strong>Σ<sub>2</sub></strong>, return (<strong>&Delta;<sub>2</sub></strong>, <strong>Σ<sub>2</sub></strong>).<br> (Similar for the reverse.)</li> <li>Else if <strong>Δ<sub>1</sub></strong> ≠ <strong>Δ<sub>2</sub></strong>, return (<em>ambiguous</em>, <strong>Σ<sub>1</sub></strong> &cup; <strong>Σ<sub>2</sub></strong>).</li> <li><p>Otherwise, return (<strong>Δ<sub>1</sub></strong>, <strong>Σ<sub>1</sub></strong> &cup; <strong>Σ<sub>2</sub></strong>)</p> <pre><code>function Merge ( (Δ1, Σ1), (Δ2, Σ2) ) { function IsBaseOf(Σp, Σq) { for (B1 in Σp) { if (not any(B1 is base of C for (C in Σq))) return false; } return true; } if (Σ1 .IsBaseOf. Σ2) return (Δ2, Σ2); else if (Σ2 .IsBaseOf. Σ1) return (Δ1, Σ1); else { Σ = Σ1 union Σ2; if (Δ1 != Δ2) Δ = ambiguous; else Δ = Δ1; return (Δ, Σ); } } </code></pre></li> </ul></li> </ol> <hr> <p>For example <sub>(&sect;10.2/10)</sub>,</p> <pre><code>struct V { int f(); }; struct W { int g(); }; struct B : W, virtual V { int f(); int g(); }; struct C : W, virtual V { }; struct D : B, C { void glorp () { f(); g(); } }; </code></pre> <p>We compute that</p> <pre><code>S(f, D) = S(f, B from D) .Merge. S(f, C from D) = ({B::f}, {B from D}) .Merge. S(f, W from C from D) .Merge. S(f, V) = ({B::f}, {B from D}) .Merge. empty .Merge. ({V::f}, {V}) = ({B::f}, {B from D}) // fine, V is a base class of B. </code></pre> <p>and</p> <pre><code>S(g, D) = S(g, B from D) .Merge. S(g, C from D) = ({B::g}, {B from D}) .Merge. S(g, W from C from D) .Merge. S(g, V) = ({B::g}, {B from D}) .Merge. ({W::g}, {W from C from D}) .Merge. empty = (ambiguous, {B from D, W from C from D}) // the W from C is unrelated to B. </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload