The relevant rules for the standard library types are in [res.on.functions]:
In particular, the effects are undefined in the following cases: [...] if an incomplete type (3.9) is used as a template argument when instantiating a template component, unless specifically allowed for that component.
This:
vector<A> Av;
is fine. std::vector
is allowed to be instantiated with an incomplete type, as long as it becomes complete before you use any of the members. There is an explicit exception for this in the standard in [vector.overview]:
An incomplete type T
may be used when instantiating vector
if the allocator satisfies the allocator completeness
requirements 17.6.3.5.1. T
shall be complete before any member of the resulting specialization of vector
is referenced.
There is similar wording for std::list
and std::forward_list
.
This:
map<int, A> Am;
is ill-formed. std::map
requires a complete type at point of instantiation as per the first quote. There is no exception for this container in the way that there is for vector
.
This:
pair<int, A> Ap;
cannot possibly ever work, since pair
is just a simply struct with two members. In order to have a member of type A
, you need a complete type.