Czy jest jakaś różnica między a std::pair
a, gdy std::tuple
ma tylko dwóch członków? (Poza oczywistym, że std::pair
wymaga dwóch i tylko dwóch członków i tuple
może mieć mniej więcej ...)
92
Istnieje kilka różnic:
std::tuple
nigdy nie może być według układu standardowego (przynajmniej nie jest to wymagane przez standard). Każdy std::pair<T, Y>
jest układem standardowym, jeśli oba T
i Y
są układem standardowym.
Trochę łatwiej jest uzyskać zawartość a pair
niż a tuple
. Musisz użyć wywołania funkcji w tuple
przypadku, gdy pair
sprawa jest tylko polem składowym.
Ale to jest o tym.
.first
i.second
są przydatne, nie oferują żadnej pomocy, jeśli trzeci (lub więcej) członek jest wymagany w zmianie kodu. Zauważyłem, że zwykle używamstd::get
niezależnie od jakichkolwiek Gettersów, w ten sposób nie muszę zmieniać wszystkiego, tylko typy danych i wszelkiemake_pair
wywołaniamake_tuple
wywołań.std::map
używastd::pair<const Key,T>
jakovalue_type
parzysty w C ++ 11. Gdzie dokładnie są używane krotkistd::map
?std::map
.Jest to bardzo późna odpowiedź, ale zwróć uwagę, że ponieważ
std::pair
jest zdefiniowana za pomocą zmiennych składowych, jego rozmiaru nie można zoptymalizować przy użyciu optymalizacji pustej klasy bazowej (first
isecond
musi zajmować odrębne adresy, nawet jeśli jedna lub obie są pustymi klasami). Pogarsza to wszelkie wymagania dotyczące dopasowaniasecond_type
, więc w najgorszym przypadku wynikstd::pair
będzie zasadniczo dwukrotnie większy niż powinien.std::tuple
zezwala na dostęp tylko przez funkcje pomocnicze, więc jest możliwe, aby wywodził się z dowolnego typu, jeśli jeden lub drugi jest pusty, oszczędzając na narzutach. Implementacja GCC przynajmniej zdecydowanie to robi ... możesz przejrzeć nagłówki, aby to sprawdzić, ale jest też to jako dowód.źródło
[[no_unique_address]]
powinien usunąć tęstd::pair
wadę.std::tuple
Name „s jest dłuższy (jeden dodatkowy znak). Więcej tych znaków jest wpisywanych prawą ręką, więc większości ludzi jest to łatwiejsze do wpisania.To powiedziawszy,
std::pair
może mieć tylko dwie wartości - nie zero, jeden, trzy lub więcej. DWIE wartości. Jednak krotka nie ma prawie żadnego ograniczenia semantycznego co do liczby wartości. Wstd::pair
związku z tym bardziej dokładny jest bezpieczny typ, którego można użyć, jeśli faktycznie chcesz określić parę wartości.źródło
std::tuple<>
jest również bezpieczny dla typów (jak mogłoby to nie być?) I2
nie różni się semantycznie odpair
.Zauważ, że w C ++ 17 można używać tego samego interfejsu do odczytywania danych zarówno z pary, jak i krotki z dwoma elementami.
auto [a, b] = FunctionToReturnPairOrTuple();
Nie ma potrzeby używania
get<>
:)źródło
Co jest warte, uważam, że wyjście GDB std :: tuple jest znacznie trudniejsze do odczytania. Oczywiście, jeśli potrzebujesz więcej niż 2 wartości, wtedy std :: pair nie zadziała, ale uważam to za punkt na korzyść struktur.
źródło
std::get<0>(tupleName)
geterem;GetX()
jest dużo łatwiejszy do odczytania i krótszy. Ma małą wadę, że jeśli zapomnisz, aby toconst
sposób ktoś może zrobić coś głupiego tak:GetX() = 20;
.