¿Caso de uso de C++11 para la construcción por partes de par y tupla?


En N3059encontré la descripción de 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 emplace y entidades no copiables, pero cuando lo probé, no pude crear un caso en el que necesitara piecewiese_construct o podría ver un beneficio de rendimiento.

Ejemplo. Pensé que necesitan una clase que es no copiable pero movebale (requerido para el reenvío):

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 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 alrededor" en lugar de copiarlo en todas partes en el stdlib, es que debe ser.

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

pair<NoCopy,NoCopy> y(
    piecewise_construct,
    forward_as_tuple(1,2),
    forward_as_tuple(2,3)
); // also fine
  • Entonces, ¿qué es un caso de uso ?
  • ¿Cómo y cuándo uso piecewise_construct?
Author: chema989, 2011-05-28

1 answers

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

El punto con las funciones emplace y piecewise_construct es que tal clase se puede construir en su lugar, sin necesidad de crear instancias temporales para ser movidas o copiadas.

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 pair(big(1,2), big(3,4)) donde dos objetos temporales big tendrían para ser creado y luego copiado - y mover no ayuda aquí en absoluto! Del mismo modo:

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

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

std::map<int, big> map;
map.emplace(std::piecewise_construct, /*key*/1, /*value*/{2,3});
 29
Author: JohannesD,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-05-28 17:55:53