Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>Your virtual function <code>A::foo()</code> returns an <code>A*</code>, while function <code>B&lt;C&gt;::foo()</code>, which is meant to override it, returns a <code>C*</code>.</p> <p>This in theory does respect the principle of covariance, since <code>C</code> is indeed a specialization of (derives from) <code>A</code>, but at the point of instantiation, this is not known, because <code>C</code> is an incomplete type.</p> <p>One possible way to re-think your design is to make <code>A</code> a class template as well, and let <code>B</code> propagate the template argument for <code>T</code> up to <code>A</code>:</p> <pre><code>template&lt;typename T&gt; class A { virtual T* foo() = 0; }; template&lt;class T&gt; class B : public A&lt;T&gt; { virtual T* foo() { return nullptr; } }; </code></pre> <p>Concerning your workaround:</p> <blockquote> <p>What does the standard states about this situation? Should this code compile? If not, why?</p> </blockquote> <p>It shouldn't compile, because the mere fact of making <code>C</code> also derive from <code>A</code> explicitly (notice, that you would end up with <em>two</em> distinct base sub-objects of type <code>A</code> inside <code>C</code>) does not make <code>C</code> a complete type when instantiating <code>B&lt;C&gt;</code>. Per Paragraph 9.2/2 of the C++11 Standard:</p> <blockquote> <p><strong>A class is considered a completely-defined object type (3.9) (or complete type) at the closing <code>}</code> of the <em>class-specifier</em>.</strong> Within the class <em>member-specification</em>, the class is regarded as complete within function bodies, default arguments, and <em>brace-or-equal-initializers</em> for non-static data members (including such things in nested classes). Otherwise it is regarded as incomplete within its own class <em>member-specification</em>. </p> </blockquote>
 

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