Il requisito (23.3.6.3:10) su vector.resize(n)
essendo ben formata è che T
dovrebbe essere CopyInsertable
, vale a dire che il seguente dovrebbe essere ben formato (23.2.1: 13):
allocator_traits<A>::construct(m, p, v);
dove A
è il tipo di allocatore del vettore, m
è l'allocatore, p
è di tipo T *
e v
è di tipo T
.
Come si può scoprire da 20.6.8.2:5, questo non è valido per i tipi di array nel caso generale in quanto è equivalente alla chiamata
::new(static_cast<void *>(p))block(v);
che è valida per i tipi di array (matrici non possono essere inizializzati parentesi).
In realtà, hai ragione che g ++ ha un bug; dovrebbe essere sempre possibile aggirare il problema con CopyInsertable
fornendo un allocatore appropriato, ma g ++ non riesce a permettere questo:
#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
}
Un altro problema è nella norma stessa; 20.9.4.3:3 specifica std::is_default_constructible<T>
come equivalente a std::is_constructible<T>
, dove 20.9.4.3:6 specifica std::is_constructible<T, Args...>
come criterio di ben formata su T t(std::declval<Args>()...)
, che è valido per i tipi di array (come @Johannes Schaub-litb sottolinea, i tipi di array possono essere inizializzati con (zero-pack-expansion)
). Tuttavia, 17.6.3.1:2 richiede per DefaultConstructible
inoltre che T()
sia ben formato, il che non è il caso per un tipo di array T
ma non è controllato da std::is_default_constructible
.
Utilizzare questa definizione di blocco: 'blocco struct {int arr [4]; }; ' – PiotrNycz
possibile duplicato di [errore del compilatore con C++ std :: vector of array] (http://stackoverflow.com/questions/12184828/compiler-error-with-c-stdvector-of-array) –
@PiotrNycz: Al contrario di 'std :: array'? –
ildjarn