<p>If I create a class like so:  </p>

<pre><code>// B.h
#ifndef _B_H_
#define _B_H_

class B
{
private:
    int x;
    int y;
};

#endif // _B_H_
</code></pre>

<p>and use it like this:</p>

<pre><code>// main.cpp
#include &lt;iostream&gt;
#include &lt;vector&gt;

class B; // Forward declaration.

class A
{
public:
    A() {
        std::cout &lt;&lt; v.size() &lt;&lt; std::endl;
    }

private:
    std::vector&lt;B&gt; v;
};

int main()
{
    A a;
}
</code></pre>

<p>The compiler fails when compiling <code>main.cpp</code>. Now the solution I know is to <code>#include "B.h"</code>, but I'm curious as to why it fails. Neither <code>g++</code> or <code>cl</code>'s error messages were very enlightening in this matter.</p>

[{'answer_id': 37347, 'author': 'Josh', 'author_id': 257, 'author_profile': 'https://Stackoverflow.com/users/257', 'pm_score': 3, 'selected': False, 'text': '<p>To instantiate A::v, the compiler needs to know the concrete type of B.</p>\n\n<p>If you\'re trying to minimize the amount of #included baggage to improve compile times, there are two things you can do, which are really variations of each other:</p>\n\n<ol>\n<li>Use a pointer to B</li>\n<li>Use a lightweight <a href="http://en.wikipedia.org/wiki/Proxy_pattern" rel="noreferrer">proxy</a> to B</li>\n</ol>\n'}, {'answer_id': 37348, 'author': 'Curt Hagenlocher', 'author_id': 533, 'author_profile': 'https://Stackoverflow.com/users/533', 'pm_score': 6, 'selected': True, 'text': '<p>The compiler needs to know how big "B" is before it can generate the appropriate layout information.  If instead, you said <code>std::vector&lt;B*&gt;</code>, then the compiler wouldn\'t need to know how big B is because it knows how big a pointer is.</p>\n'}, {'answer_id': 37350, 'author': 'Brad Wilson', 'author_id': 1554, 'author_profile': 'https://Stackoverflow.com/users/1554', 'pm_score': -1, 'selected': False, 'text': "<p>The reason you can't use a forward declaration is because the size of B is unknown.</p>\n\n<p>There's no reason in your example that you can't include B.h inside of A.h, so what problem are you really trying to solve?</p>\n\n<p><strong>Edit:</strong> There's another way to solve this problem, too: stop using C/C++! It's so 1970s... ;)</p>\n"}, {'answer_id': 139062, 'author': 'MSalters', 'author_id': 15416, 'author_profile': 'https://Stackoverflow.com/users/15416', 'pm_score': 2, 'selected': False, 'text': "<p>It's more than just the size of B that's needed. Modern compilers will have fancy tricks to speed up vector copies using memcpy where possible, for instance. This is commonly achieved by partially specializing on the POD-ness of the element type. You can't tell if B is a POD from a forward declaration.</p>\n"}, {'answer_id': 139294, 'author': 'Greg Rogers', 'author_id': 5963, 'author_profile': 'https://Stackoverflow.com/users/5963', 'pm_score': 1, 'selected': False, 'text': "<p>This doesn't matter whether you use a vector or just try to instantiate one B. Instantiation requires the full definition of an object.</p>\n"}, {'answer_id': 14010890, 'author': 'daotheman', 'author_id': 1924938, 'author_profile': 'https://Stackoverflow.com/users/1924938', 'pm_score': 0, 'selected': False, 'text': "<p>Man, you're instancing <code>std::vector</code> with an incomplete type. Don't touch the forward declaration, just move the constructor's definition to the <code>.cpp</code> file.</p>\n"}, {'answer_id': 15382714, 'author': 'fyzix', 'author_id': 2164823, 'author_profile': 'https://Stackoverflow.com/users/2164823', 'pm_score': 5, 'selected': False, 'text': '<p>In fact your example would build if A\'s constructor were implemented in a compile unit that knows the type of B.</p>\n\n<p>An std::vector instance has a fixed size, no matter what T is, since it contains, as others said before, only a pointer to T. But the vector\'s constructor depends on the concrete type. Your example doesn\'t compile because A() tries to call the vector\'s ctor, which can\'t be generated without knowing B. Here\'s what would work:</p>\n\n<p>A\'s declaration:</p>\n\n<pre><code>// A.h\n#include &lt;vector&gt;\n\nclass B; // Forward declaration.\n\nclass A\n{\npublic:\n    A(); // only declare, don\'t implement here\n\nprivate:\n    std::vector&lt;B&gt; v;\n};\n</code></pre>\n\n<p>A\'s implementation:</p>\n\n<pre><code>// A.cpp\n#include "A.h"\n#include "B.h"\n\nA::A() // this implicitly calls vector&lt;B&gt;\'s constructor\n{\n    std::cout &lt;&lt; v.size() &lt;&lt; std::endl;\n}\n</code></pre>\n\n<p>Now a user of A needs to know only A, not B:</p>\n\n<pre><code>// main.cpp\n#include "A.h"\n\nint main()\n{\n    A a; // compiles OK\n}\n</code></pre>\n'}, {'answer_id': 28569371, 'author': 'Raslanove', 'author_id': 1942069, 'author_profile': 'https://Stackoverflow.com/users/1942069', 'pm_score': 2, 'selected': False, 'text': '<p>Just like fyzix said, the reason your forward declaration is not working is because of your inline constructor. Even an empty constructor might contain lots of code, like the construction of non-POD members. In your case, you have a vector to initialize, which you can\'t do without defining its template type completely. </p>\n\n<p>The same goes for destructors. The vector needs the template type definition to tell what destructor to call when destroying the instances it holds.</p>\n\n<p>To get rid of this problem, just don\'t inline constructors and destructors. Define them separately somewhere after B is completely defined.</p>\n\n<p>For more information,\n<a href="http://www.chromium.org/developers/coding-style/cpp-dos-and-donts" rel="nofollow">http://www.chromium.org/developers/coding-style/cpp-dos-and-donts</a></p>\n'}]
['https://Stackoverflow.com/questions/37346', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/61/']