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 ...)
Odpowiedzi:
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.
std::map
używa std::pair<const Key,T>
jako value_type
parzysty w C ++ 11. Gdzie dokładnie są używane krotki std::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
i second
musi zajmować odrębne adresy, nawet jeśli jedna lub obie są pustymi klasami). Pogarsza to wszelkie wymagania dotyczące dopasowania second_type
, więc w najgorszym przypadku wynik std::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.
[[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. W std::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.
std::tuple<>
jest również bezpieczny dla typów (jak mogłoby to nie być?) I 2
nie różni się semantycznie od pair
.
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.
std::get<0>(tupleName)
geterem; GetX()
jest dużo łatwiejszy do odczytania i krótszy. Ma małą wadę, że jeśli zapomnisz, aby to const
sposób ktoś może zrobić coś głupiego tak: GetX() = 20;
.
.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ń.