¿Hay alguna diferencia entre an std::pairy an std::tuplecon solo dos miembros? (Además de lo obvio que std::pairrequiere dos y solo dos miembros y tuplepuede tener más o menos ...)
92
Hay algunas diferencias:
std::tuplenunca puede ser por diseño estándar (al menos, no es requerido por el estándar). Cada std::pair<T, Y>es de diseño estándar si ambos Ty Yson de diseño estándar.
Es un poco más fácil obtener el contenido de pairun tuple. Debe usar una llamada de función en el tuplecaso, mientras que el paircaso es solo un campo miembro.
Pero eso es todo.
.firsty.secondson útiles, no ofrecen ayuda si se requiere un tercer (o más) miembro (s) en un cambio de código. He notado que tiendo a usarstd::getindependientemente en cualquier Getter de esa manera, no necesito cambiar todo, solo los tipos de datos y lasmake_pairllamadas a lasmake_tuplellamadas.std::mapusastd::pair<const Key,T>comovalue_typepar en C ++ 11. ¿Dónde se usan exactamente las tuplasstd::map?std::map.Esta es una respuesta muy tardía, pero tenga en cuenta que, debido a que
std::pairse define con variables miembro, su tamaño no se puede optimizar utilizando la optimización de clase base vacía (firstyseconddebe ocupar direcciones distintas, incluso si una o ambas son clases vacías). Esto se ve agravado por los requisitos de alineación quesecond_typetenga, por lo que, en el peor de los casos, el resultadostd::pairserá básicamente el doble del tamaño que necesita.std::tuplesolo permite el acceso a través de funciones auxiliares, por lo que es posible que se derive de cualquier tipo si uno u otro está vacío, ahorrando en la sobrecarga. La implementación de GCC, al menos, definitivamente hace esto ... puede revisar los encabezados para verificar esto, pero también hay esto como evidencia.fuente
[[no_unique_address]]debería eliminarstd::pairla desventaja.El
std::tuplenombre de An es más largo (un carácter adicional). Más de esos caracteres se escriben con la mano derecha, por lo que es más fácil para la mayoría de las personas escribir.Dicho esto,
std::pairsolo puede tener dos valores: no cero, uno, tres o más. DOS valores. Una tupla, sin embargo, casi no tiene limitación semántica en el número de valores. Anstd::pair, por lo tanto, es un tipo seguro de tipo más preciso para usar si realmente desea especificar un par de valores.fuente
std::tuple<>es de tipo seguro (¿cómo no podría serlo?), Y no es semánticamente diferente a .2pairTenga en cuenta que con C ++ 17, se puede usar la misma interfaz para leer datos tanto de pares como de tuplas con dos elementos.
auto [a, b] = FunctionToReturnPairOrTuple();No es necesario usar
get<>:)fuente
Por lo que vale, encuentro que la salida GDB de std :: tuple es mucho más difícil de leer. Obviamente, si necesita más de 2 valores, std :: pair no funcionará, pero considero que esto es un punto a favor de las estructuras.
fuente
std::get<0>(tupleName)en un captador;GetX()es mucho más fácil de leer y más corto. Tiene una pequeña desventaja de que si se olvida de que sea unconstmétodo que alguien puede hacer algo estúpido como esto:GetX() = 20;.