c++11 - automatic - personal hashtags



Caso d'uso C++ 11 per la combinazione piecewise_construct di coppia e tupla? (1)

Non tutti i tipi possono essere spostati in modo più efficiente rispetto a quelli copiati e, per alcuni tipi, potrebbe avere senso disabilitare in modo esplicito sia la copia che lo spostamento. Considera std::array<int, BIGNUM> come un esempio del primo tipo di un tipo.

Il punto con le funzioni emplace e piecewise_construct è che tale classe può essere costruita sul posto , senza la necessità di creare istanze temporanee da spostare o copiare.

struct big {
    int data[100];
    big(int first, int second) : data{first, second} {
        // the rest of the array is presumably filled somehow as well
    }
};

std::pair<big, big> pair(piecewise_construct, {1,2}, {3,4});

Confronta il precedente per pair(big(1,2), big(3,4)) dove due oggetti temporanei dovrebbero essere creati e poi copiati - e lo spostamento non aiuta affatto! Allo stesso modo:

std::vector<big> vec;
vec.emplace_back(1,2);

Il caso d'uso principale per la costruzione a tratti di una coppia è l'inserimento di elementi in una map o in una map unordered_map :

std::map<int, big> map;
map.emplace(std::piecewise_construct, /*key*/1, /*value*/{2,3});

In N3059 ho trovato la descrizione della costruzione a tratti di coppie (e tuple) (ed è nel nuovo standard).

Ma non riesco a vedere quando dovrei usarlo. Ho trovato discussioni su emplace e entità non copiabili, ma quando l'ho provato, non sono riuscito a creare un caso in cui avessi bisogno di piecewiese_construct o potessi vedere un vantaggio in termini di prestazioni.

Esempio. Pensavo di aver bisogno di una classe che non è copiabile , ma movebale (necessaria per l'inoltro):

struct NoCopy {
  NoCopy(int, int) {};
  NoCopy(const NoCopy&) = delete; // no copy
  NoCopy& operator=(const NoCopy&) = delete; // no assign
  NoCopy(NoCopy&&) {}; // please move
  NoCopy& operator=(NoCopy&&) {}; // please move-assign
};

Allora mi aspetto - mi aspettavo che la costruzione della coppia standard fallisse:

pair<NoCopy,NoCopy> x{ NoCopy{1,2}, NoCopy{2,3} }; // fine!

ma non è stato così. In realtà, questo è quello che mi sarei aspettato in ogni caso, perché "spostare le cose in giro" piuttosto che copiarlo ovunque nello stdlib, dovrebbe essere.

Quindi, non vedo alcuna ragione per cui avrei dovuto farlo, o così:

pair<NoCopy,NoCopy> y(
    piecewise_construct,
    forward_as_tuple(1,2),
    forward_as_tuple(2,3)
); // also fine
  • Quindi, qual è l' usecase ?
  • Come e quando utilizzare piecewise_construct ?




piecewise