In and of themselves, there is no reason that template type arguments need to be complete types (in fact, 14.3.1/2 explicitly states that this is not the case).
Such a requirement then comes from how that type is used within the definition of your type template (in this case, std::vector
). For example, [C++11: 20.7.1/5]
states that the template argument T
of a std::unique_ptr<T>
may be incomplete at the point of the unique_ptr
's declaration; this is stated explicitly because it was not the case for std::auto_ptr
.
You'll find that as soon as you try to do pretty much anything with your vector, you'll need that T
to be complete. This issue is detectable at compile-time as it all comes down to the instantiation of templates, so your compiler will do the appropriate erroring as and when required.
The vector's destructor is usually one of those things.
So, using GCC 4.8, I cannot instantiate either vector with an incomplete value_type
:
#include <vector>
class Foo;
class Bar;
std::vector<Foo> foos;
std::vector<Bar> bars;
int main() {}
error: invalid use of incomplete type 'class Foo'
error: invalid use of incomplete type 'class Bar'
Only when I use them as members in a class that never gets used is the entire thing compilable, because the vectors' destructors are never invoked and therefore never template-instantiated:
#include <vector>
class Foo;
class Bar;
class T
{
std::vector<Foo> foos;
std::vector<Bar> bars;
};
int main() {}
(no error)
Whatever your implementation does, it'll be the same for both Foo
and Bar
; if you're seeing a difference between them, then you must be doing something different with Bar
that you have not shown us.