Reputation: 28279
I have used forward declarations a lot; they help avoid many #include
s, improve compilation time and what not. But what if i want to forward-declare a class in the standard library?
// Prototype of my function - i don't want to include <vector> to declare it!
int DoStuff(const std::vector<int>& thingies);
I have heard it's forbidden/impossible to forward-declare std::vector
. Now this answer to an unrelated question suggests to rewrite my code this way:
stuff.h
class VectorOfNumbers; // this class acts like std::vector<int>
int DoStuff(const VectorOfNumbers& thingies);
stuff.cpp
// Implementation, in some other file
#include <vector>
class VectorOfNumbers: public std::vector<int>
{
// Define the constructors - annoying in C++03, easy in C++11
};
int DoStuff(const VectorOfNumbers& thingies)
{
...
}
Now, if i use VectorOfNumbers
instead of std::vector<int>
in all contexts throughout my project, everything is going to be good, and i don't need to #include <vector>
in my header files anymore!
Does this technique have major disadvantages? Can the gain of being able to forward-declare vector
outweigh them?
Upvotes: 2
Views: 1598
Reputation: 11926
Instead of inheritance, you could use composition:
// Implementation, in some other file
#include <vector>
class VectorOfNumbers
{
public:
std::vector<int>& container;
VectorOfNumbers(std::vector<int>& in_container)
: container(in_container)
{
}
};
int DoStuff(const VectorOfNumbers& thingies)
{
std::sort(thingies.container.begin(), thingies.container.end());
// ...
}
The downside is the extra variable name on every access.
Also, you'd need this implementation to be in a header file included by cpps so they will know what they can do with VectorOfNumbers.
Essentially, just making a wrapper for your vector. This is like a light-weight version of PImpl (we only care about avoiding header dependencies so we don't need the full pointer decoupling). It avoids the issues raised by Mark B and ybungalobill.
But I don't think it's really worth it.
Upvotes: 0
Reputation: 72489
The reason I wouldn't do this:
const std::vector<int>& a = a_3rd_party_lib::get_data(); // this type is out of your control
DoStuff(a); // you cannot pass it to this function!
Upvotes: 3
Reputation: 308276
This works well for the interface for a class, but not for the implementation. If your class has any vector
members you must #include <vector>
or the class definition will not compile.
Upvotes: 0
Reputation: 96271
If you ever delete a VectorOfNumbers
as a std::vector<int>
(and since you used public inheritance this conversion is implicit) you've entered the realm of undefined behavior. This is probably more likely to accidentally happen than one might suspect.
I've never personally noticed significant compilation slowdown from just including vector
where needed, but if you really want to isolate the include, use a client API interface that doesn't know about the underlying container type (vector
) and pimpl the vector
include into a single source file.
Upvotes: 6
Reputation: 7336
You include <vector>
in your header file. The <vector>
header will have been built to prevent multiple inclusions, so you just include it everywhere you need it.
Upvotes: 0