Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't a forward declaration be used for a std::vector?

Tags:

c++

stl

If I create a class like so:

// B.h #ifndef _B_H_ #define _B_H_  class B { private:     int x;     int y; };  #endif // _B_H_ 

and use it like this:

// main.cpp #include <iostream> #include <vector>  class B; // Forward declaration.  class A { public:     A() {         std::cout << v.size() << std::endl;     }  private:     std::vector<B> v; };  int main() {     A a; } 

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

like image 589
Bernard Avatar asked Sep 01 '08 01:09

Bernard


People also ask

What is forward declaration and where we can use this?

A forward declaration tells the compiler about the existence of an entity before actually defining the entity. Forward declarations can also be used with other entity in C++, such as functions, variables and user-defined types.

Why should I use forward declarations?

A forward declaration allows us to tell the compiler about the existence of an identifier before actually defining the identifier. In the case of functions, this allows us to tell the compiler about the existence of a function before we define the function's body.

What is forward declaration in C++?

In C++ the forward declaration lets the code following the declaration know that there is are classes with the name Person. This satisfies the compiler when it sees these names used. Later the linker will find the definition of the classes.

Do C++ need forward declarations?

Forward declarations means the declaration of a method or variable prior to its implementation. Such declaration is necessary in C/C++ programming language in order to be able to use a variable or object before its implementation.


1 Answers

In fact your example would build if A's constructor were implemented in a compile unit that knows the type of B.

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:

A's declaration:

// A.h #include <vector>  class B; // Forward declaration.  class A { public:     A(); // only declare, don't implement here  private:     std::vector<B> v; }; 

A's implementation:

// A.cpp #include "A.h" #include "B.h"  A::A() // this implicitly calls vector<B>'s constructor {     std::cout << v.size() << std::endl; } 

Now a user of A needs to know only A, not B:

// main.cpp #include "A.h"  int main() {     A a; // compiles OK } 
like image 90
fyzix Avatar answered Sep 21 '22 07:09

fyzix