Note that there are some explanatory texts on larger screens.

plurals
  1. POForward declaration, unique_ptr and in-class initializer
    primarykey
    data
    text
    <p>I have read <a href="https://stackoverflow.com/q/6012157/563765">Is std::unique_ptr&lt;T&gt; required to know the full definition of T?</a> and <a href="https://stackoverflow.com/q/13414652/563765">Forward declaration with unique_ptr?</a>, but my question is more specific.</p> <p>The following compiles:</p> <pre><code>// Compile with $ g++ -std=c++11 -c &lt;filename&gt; #include &lt;memory&gt; class A; // fwd declaration class AUser { AUser(); // defined elsewhere ~AUser(); // defined elsewhere std::unique_ptr&lt;A&gt; m_a; }; </code></pre> <p>The following doesn't:</p> <pre><code>// Compile with $ g++ -std=c++11 -c &lt;filename&gt; #include &lt;memory&gt; class A; // fwd declaration class AUser { AUser(); // defined elsewhere ~AUser(); // defined elsewhere std::unique_ptr&lt;A&gt; m_a{nullptr}; }; </code></pre> <p>The error</p> <pre><code>$ g++ -std=c++11 -c fwd_decl_u_ptr.cpp In file included from /usr/include/c++/4.7/memory:86:0, from fwd_decl_u_ptr.cpp:3: /usr/include/c++/4.7/bits/unique_ptr.h: In instantiation of ‘void std::default_delete&lt;_Tp&gt;::operator()(_Tp*) const [with _Tp = A]’: /usr/include/c++/4.7/bits/unique_ptr.h:173:4: required from ‘std::unique_ptr&lt;_Tp, _Dp&gt;::~unique_ptr() [with _Tp = A; _Dp = std::default_delete&lt;A&gt;]’ fwd_decl_u_ptr.cpp:9:33: required from here /usr/include/c++/4.7/bits/unique_ptr.h:63:14: error: invalid application of ‘sizeof’ to incomplete type ‘A’ </code></pre> <hr> <p>EDIT: As far as I understand, what is happening here is that the in-class initializer implies being capable of initializing <code>unique_ptr&lt;A&gt;</code> already at the moment of declaration of <code>AUser</code>. Since the type <code>unique_ptr&lt;A&gt;</code> is actually <code>unique_ptr&lt;A, default_delete&lt;A&gt;&gt;</code>, being able to initialize it implies being able to initialize <code>default_delete&lt;A&gt;</code>. And, for that, <code>A</code> has to be fully defined.</p> <p>The weak link in this reasoning is the assumption that the in-class initializer implies capability of initializing the respective data member at the moment of declaration of the class! This seems an intuitive self-evidence, since the initializer is part of the declaration. But I would be more comfortable if I found something in the standard explicitly stating that. Otherwise I can still think of implementation solutions that wouldn't require it. For instance, the compiler could simply take the initializer expression and apply it only in constructors where the initialization of the attribute wasn't explicitly given.</p> <p>So, can anyone refer me to a standard section/excerpt that implies the necessity for the full definition of A in the second case? I didn't find much about in-class initializers in the standard (only found them referred to as "<em>brace-or-equal-initializers</em> of non-static data members"), but nothing related to this.</p>
    singulars
    1. This table or related slice is empty.
    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.
 

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