Quando seguente codice:Posso ordinare il vettore di una tupla di riferimenti?
std::vector<std::tuple<int&>> v;
int a = 5; v.emplace_back(a);
int b = 4; v.emplace_back(b);
int c = 3; v.emplace_back(c);
int d = 2; v.emplace_back(d);
int e = 1; v.emplace_back(e);
std::sort(std::begin(v), std::end(v));
è compilato con gcc/libstdC++ vs clang/libC++ binario dà risultati diversi.
Per gcc/libstdc++ un elemento viene copiato su tutti gli altri riferimenti.
5 4 3 2 1
5 5 5 5 5
ho pensato che clang/libc++ comporta come previsto ma funziona solo fino a 5 elementi in un vettore (causa v'è un caso speciale per piccoli contenitori).
5 4 3 2 1
1 2 3 4 5
Quando si passa più elementi il risultato è simile a gcc.
5 4 3 2 1 0
3 4 5 5 5 5
Quindi è valido da utilizzare std::sort
per il contenitore di tuple con riferimenti (cioè realizzati con std::tie
, l'ordinamento sottoinsieme di struct)? In caso contrario, dovrei aspettarmi qualche avviso?
L'uso di 'std :: reference_wrapper' funziona perché può essere costruito da 'std :: tie' ma richiede un po 'di magia del modello per ottenere l'elenco di tipi T & ... e decorarlo con reference_wrapper. [Entrambi i compilatori] (http://melpon.org/wandbox/permlink/atQyUIr1Bh5g6qgn) concordano sul fatto che 'std :: tuple ' is_move_assignable && is_move_constructible (con i tratti normali) –
@KarolWozniak Il tratto può controllare solo se l'attuale semantica funziona - tu * puoi * spostare assegnare una 'tupla'. Semplicemente non ha il comportamento effettivo che quell'operazione deve avere per essere considerato MoveAssignable. –
Barry
@KarolWozniak Per esempio, 'struct X {int val; X & operator = (X &&) {return * this; }; '' is_move_assignable 'è vero, ma' X' non è in realtà MoveAssignable poiché il requisito non è soddisfatto. –
Barry