Czy jest jakaś różnica między a std::paira, gdy std::tuplema tylko dwóch członków? (Poza oczywistym, że std::pairwymaga dwóch i tylko dwóch członków i tuplemoże mieć mniej więcej ...)
Odpowiedzi:
Istnieje kilka różnic:
std::tuplenigdy 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 Ti Ysą układem standardowym.
Trochę łatwiej jest uzyskać zawartość a pairniż a tuple. Musisz użyć wywołania funkcji w tupleprzypadku, gdy pairsprawa jest tylko polem składowym.
Ale to jest o tym.
std::mapużywa std::pair<const Key,T>jako value_typeparzysty 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::pairjest zdefiniowana za pomocą zmiennych składowych, jego rozmiaru nie można zoptymalizować przy użyciu optymalizacji pustej klasy bazowej ( firsti secondmusi 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::pairbędzie zasadniczo dwukrotnie większy niż powinien.
std::tuplezezwala 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::pairwadę.
std::tupleName „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::pairmoż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::pairzwią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 2nie 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 constsposób ktoś może zrobić coś głupiego tak: GetX() = 20;.
.firsti.secondsą 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::getniezależnie od jakichkolwiek Gettersów, w ten sposób nie muszę zmieniać wszystkiego, tylko typy danych i wszelkiemake_pairwywołaniamake_tuplewywołań.