2
votes

I'm trying to use forward declarations as much as I can to minimize compilation time. I noticed that when I forward declare a class that is using something like std::vector as a member object (example here):

class myTypeA
class A
{
  A(){};
  ~A(){};
  std::vector<myTypeA > getTypeA();

}

I get the following error:

microsoft visual studio 9.0\vc\include\vector(1112) : error C2036: 'myTypeA *' : unknown size
1>        c:\program files\microsoft visual studio 9.0\vc\include\vector(1102) : while compiling class template member function 'bool std::vector<_Ty>::_Buy(unsigned int)'
1>        with
1>        [
1>            _Ty=myTypeA
1>        ]
1>        d:\cpp\A.h(15) : see reference to class template instantiation 'std::vector<_Ty>' being compiled
1>        with
1>        [
1>            _Ty=myTypeA
1>        ]

this is working fine when I use the #include "myTypeA.h", why ?

3

3 Answers

6
votes

This is because the compiler needs to know the size of the types to be stored in the vector. Without the full class definition it has no way of know this.

An alternative would be to store pointers to your forward-declared type - however you would need to manage the memory allocation and deallocation.

A third option would be to declare a shared_ptr type based on your forward declared type and store these in your vector.

0
votes

As the error says

error C2036: 'myTypeA *' : unknown size

Compiler would not know the size of the object of this type by forward declaration. It just tells what type is it. You need to include the header to bring in the class definition so that compiler can evaluate the size of an object of this type.

See this SO question

-1
votes

The simple answer is that the standard requires a complete definition anytime you instantiate a template over a type; it's undefined behavior otherwise. Compilers which enforce such constraints (g++, when you compile with the proper options) will fail to compiler. Others might accept it. (Although formally undefined behavior, in practice, it will either fail to compile, or work as expected.)

I'm somewhat surprised that Microsoft fails to compile the bit of code you posted, since it doesn't need to know anything about myTypeA. The message looks like something that might appear if you are calling the function; if you call the function, you'll definitely need a definition of myTypeA, since the compiler will have to instantiate the copy constructor, which in turn means copying the contained instances of myTypeA.