In C++11, there are two versions of std::vector::resize():
void resize( size_type count );
void resize( size_type count, const value_type& value);
I understand (as suggested by one of the comments to one of the answers to this question) that the first requires value_type to be default constructible, while the second requires it to be copy constructible. However, (gcc 4.7.0)
using namespace std;
typedef int block[4];
vector<block> A;
static_assert(is_default_constructible<block>::value,";-("); // does not fire
A.resize(100); // compiler error
So either my understanding was wrong or gcc is buggy. Which?
The requirement (23.3.6.3:10) on
vector.resize(n)being well-formed is thatTshould beCopyInsertable, i.e. that the following should be well-formed (23.2.1:13):where
Ais the allocator type of the vector,mis the allocator,pis of typeT *andvis of typeT.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
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
CopyInsertableby providing an appropriate allocator, but g++ fails to allow this:Another bug is in the standard itself; 20.9.4.3:3 specifies
std::is_default_constructible<T>as equivalent tostd::is_constructible<T>, where 20.9.4.3:6 specifiesstd::is_constructible<T, Args...>as the well-formedness criterion onT t(std::declval<Args>()...), 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 forDefaultConstructiblein addition thatT()be well-formed, which is not the case for an array typeTbut is not checked bystd::is_default_constructible.