c++11 tuples use-case forwarding piecewise

c++11 - C++ 11 use-case para piecewise_construct de pair y tuple?



tuples forwarding (1)

En N3059 encontré la descripción de la construcción por partes de pares (y tuplas) (y está en el nuevo estándar).

Pero no puedo ver cuándo debo usarlo. Encontré discusiones sobre entidades emplazables y no copiables, pero cuando lo probé, no pude crear un caso en el que necesitara piecewiese_construct o pudiera ver un beneficio de rendimiento.

Ejemplo. Pensé que necesitaba una clase que no se puede copiar , pero movebale (requerida para reenviar):

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 };

Entonces, de alguna manera, esperaba que la construcción de pares estándar fallara:

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

pero no lo hizo. En realidad, esto es lo que esperaba de todos modos, porque "mover cosas" en lugar de copiarlas en todas partes en la tabla de contenido, debería ser así.

Por lo tanto, no veo ninguna razón por la que debería haber hecho esto, o algo así:

pair<NoCopy,NoCopy> y( piecewise_construct, forward_as_tuple(1,2), forward_as_tuple(2,3) ); // also fine

  • Entonces, ¿qué es el caso de uso ?
  • ¿Cómo y cuándo uso piecewise_construct ?

No todos los tipos pueden moverse más eficientemente que copiarse, y para algunos tipos puede tener sentido incluso desactivar explícitamente tanto la copia como el movimiento. Considere std::array<int, BIGNUM> como un ejemplo del tipo anterior de tipo.

El punto con las funciones emplace y piecewise_construct es que dicha clase puede construirse en su lugar , sin necesidad de crear instancias temporales para mover o copiar.

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});

Compare lo anterior con el pair(big(1,2), big(3,4)) donde tendrían que crearse y copiarse dos big objetos temporales, ¡y el movimiento no ayuda en absoluto aquí! Similar:

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

El caso de uso principal para construir un par a trozos es emplazar elementos en un map o en un map unordered_map :

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