Yêu cầu (23.3.6.3:10) trên vector.resize(n)
được tốt được hình thành là T
nên CopyInsertable
, tức là sau đây cần được tốt được hình thành (23.2.1: 13):
allocator_traits<A>::construct(m, p, v);
nơi A
là loại phân bổ của vectơ, m
là người cấp phát, p
thuộc loại T *
và v
thuộc loại T
.
Như bạn có thể khám phá từ 20.6.8.2:5, đây là không hợp lệ với nhiều loại mảng trong trường hợp tổng quát vì nó là tương đương với gọi
::new(static_cast<void *>(p))block(v);
đó là không hợp lệ với nhiều loại mảng (mảng không thể được khởi tạo bởi dấu ngoặc đơn).
Thực ra, bạn nói đúng rằng g ++ có lỗi; nó nên luôn luôn có thể làm việc xung quanh vấn đề này với CopyInsertable
bằng cách cung cấp một cấp thích hợp, nhưng g ++ không cho phép điều này:
#include <vector>
template<typename T, int n> struct ArrayAllocator: std::allocator<T[n]> {
void construct(T (*p)[n], T (&v)[n]) {
for (int i = 0; i < n; ++i)
::new(static_cast<void *>(p + i)) T{v[i]};
}
};
int main() {
std::vector<int[4], ArrayAllocator<int, 4>> c;
c.resize(100); // fails
typedef ArrayAllocator<int, 4> A;
A m;
int (*p)[4] = 0, v[4];
std::allocator_traits<A>::construct(m, p, v); // works
}
lỗi khác là trong tiêu chuẩn riêng của mình; 20.9.4.3:3 chỉ định std::is_default_constructible<T>
tương đương với std::is_constructible<T>
, trong đó 20.9.4.3:6 chỉ định std::is_constructible<T, Args...>
làm tiêu chí chính xác trên T t(std::declval<Args>()...)
, có giá trị cho các loại mảng (như @Johannes Schaub-litb chỉ ra, các loại mảng có thể được khởi tạo với (zero-pack-expansion)
). Tuy nhiên, 17.6.3.1:2 yêu cầu đối với DefaultConstructible
ngoài ra, T()
được định dạng đúng, không phải là trường hợp đối với loại mảng T
nhưng không được kiểm tra bởi std::is_default_constructible
.
Sử dụng định nghĩa khối này: 'struct khối {int arr [4]; }; ' – PiotrNycz
có thể trùng lặp của [lỗi trình biên dịch với C++ std :: vectơ của mảng] (http://stackoverflow.com/questions/12184828/compiler-error-with-c-stdvector-of-array) –
@PiotrNycz: Trái với 'std :: array'? –
ildjarn