Existe uma diferença entre um std::pair
e um std::tuple
com apenas dois membros? (Além do óbvio que std::pair
requer dois e apenas dois membros e tuple
pode ter mais ou menos ...)
95
Existem algumas diferenças:
std::tuple
não é exigido pelo padrão para ser um layout padrão . Cada um std::pair<T, Y>
é de layout padrão se ambos T
e Y
são de layout padrão.
É um pouco mais fácil obter o conteúdo de a do pair
que de a tuple
. Você tem que usar uma chamada de função no tuple
caso, enquanto o pair
caso é apenas um campo de membro.
Mas é isso aí.
.first
e.second
sejam úteis, eles não oferecem nenhuma ajuda se um terceiro (ou mais) membro (s) forem necessários para uma mudança de código. Percebi que tenho tendência a usarstd::get
independentemente em qualquer Getters, dessa forma, não preciso alterar tudo, apenas os tipos de dados e quaisquermake_pair
chamadas paramake_tuple
chamadas.std::map
usastd::pair<const Key,T>
comovalue_type
mesmo em C ++ 11. Onde exatamente as tuplas são usadasstd::map
?std::map
.O
std::tuple
nome de um é mais longo (um caractere extra). Mais desses caracteres são digitados com a mão direita, portanto, mais fáceis para a maioria das pessoas digitar.Dito isso,
std::pair
pode ter apenas dois valores - não zero, um, três ou mais. DOIS valores. Uma tupla, entretanto, quase não tem limitação semântica no número de valores. Umstd::pair
, portanto, é um tipo de tipo seguro mais preciso a ser usado se você realmente deseja especificar um par de valores.fonte
std::tuple<>
é seguro para tipos (como não poderia ser?) E não é semanticamente diferente de .2
pair
Esta é uma resposta muito tardia, mas observe que, por
std::pair
ser definido com variáveis de membro, seu tamanho não pode ser otimizado usando a otimização de classe base vazia (first
esecond
deve ocupar endereços distintos, mesmo se uma ou ambas forem uma classe vazia). Isso é exacerbado por quaisquer requisitos de alinhamentosecond_type
, portanto, no pior caso, o resultadostd::pair
será basicamente o dobro do tamanho que precisa ser.std::tuple
só permite acesso por meio de funções auxiliares, portanto, é possível derivar de qualquer tipo se um ou outro estiver vazio, economizando na sobrecarga. A implementação do GCC, pelo menos, definitivamente faz isso ... você pode vasculhar os cabeçalhos para verificar isso, mas também há isso como evidência.fonte
[[no_unique_address]]
deve removerstd::pair
a desvantagem de.Observe que, com C ++ 17, pode-se usar a mesma interface para ler dados de pares e tuplas com dois elementos.
auto [a, b] = FunctionToReturnPairOrTuple();
Não há necessidade de usar
get<>
:)fonte
Pelo que vale a pena, acho que a saída do GDB de std :: tuple é muito mais difícil de ler. Obviamente, se você precisar de mais de 2 valores, std :: pair não funcionará, mas eu considero isso um ponto a favor de structs.
fonte
std::get<0>(tupleName)
em um getter;GetX()
é muito mais fácil de ler e mais curto. Ele tem uma pequena desvantagem que se você se esqueça de torná-lo umconst
alguém método pode fazer algo estúpido assim:GetX() = 20;
.