In C++11, there are two versions of std::vector::resize():
void resize( size_type count );
void resize( size_type count, const value_type& v
The requirement (23.3.6.3:10) on vector.resize(n) being well-formed is that T should be CopyInsertable, i.e. that the following should be well-formed (23.2.1:13):
allocator_traits::construct(m, p, v);
where A is the allocator type of the vector, m is the allocator, p is of type T * and v is of type T.
As you can discover from 20.6.8.2:5, this is invalid for array types in the general case as it is equivalent to calling
::new(static_cast(p))block(v);
which is invalid for array types (arrays cannot be initialized by parentheses).
Actually, you're correct that g++ has a bug; it should always be possible to work around the issue with CopyInsertable by providing an appropriate allocator, but g++ fails to allow this:
#include
template struct ArrayAllocator: std::allocator {
void construct(T (*p)[n], T (&v)[n]) {
for (int i = 0; i < n; ++i)
::new(static_cast(p + i)) T{v[i]};
}
};
int main() {
std::vector> c;
c.resize(100); // fails
typedef ArrayAllocator A;
A m;
int (*p)[4] = 0, v[4];
std::allocator_traits::construct(m, p, v); // works
}
Another bug is in the standard itself; 20.9.4.3:3 specifies std::is_default_constructible as equivalent to std::is_constructible, where 20.9.4.3:6 specifies std::is_constructible as the well-formedness criterion on T t(std::declval, which is valid for array types (as @Johannes Schaub-litb points out, array types can be initialised with (zero-pack-expansion)). However, 17.6.3.1:2 requires for DefaultConstructible in addition that T() be well-formed, which is not the case for an array type T but is not checked by std::is_default_constructible.