Sadece iki üyeli std :: pair ve std :: tuple arasındaki fark nedir?


92

Sadece iki üyesi olan bir std::pairve bir arasında bir fark var mı std::tuple? (Açık olanın yanı sıra, std::pairiki ve yalnızca iki üye gerektirir ve tupleaz ya da çok olabilir ...)

Yanıtlar:


86

Bazı farklılıklar var:

  1. std::tupleasla standart düzende olamaz (en azından standart olması gerekmez ). Her std::pair<T, Y>ikisi de standart düzendir Tve Yher ikisi de standart düzendir.

  2. Bir içeriğini almak için biraz daha kolay pairbir daha tuple. Durum sadece bir üye alanı tupleiken, pairdurumda bir işlev çağrısı kullanmanız gerekir .

Ama bununla ilgili.


5
"Verileri bir çiftten almak bir demetten biraz daha kolay. Biraz." Farkettim. : P Kullanışlı olmasına .firstve olmasına rağmen .second, bir kod değişikliğinde üçüncü (veya daha fazla) üye gerekiyorsa yardım sunmazlar. std::getHerhangi bir Getters'da ne olursa olsun kullanmaya meyilli olduğumu fark ettim , bu şekilde her şeyi değiştirmeme gerek yok, sadece veri türlerini ve make_pairçağrılara yapılan make_tupleçağrıları.
Casey

Bu anlaşılmaktadır std::mapkullanımlarını std::pair<const Key,T>olarak value_typebile C ++ 11. Tuples tam olarak nerede kullanılır std::map?
nknight

@nknight: ... Bunu neden söylediğime dair hiçbir fikrim yok. Ya da bunun yerine söylemek istediğim şey std::map.
Nicol Bolas

1
@Yakk: Um, "" tuşuna basıyorum. ve IDE’im bir üye listesi getiriyor. İnsanların buna ihtiyacı olduğunu düşünmemiştim.
Nicol Bolas

2
Acaba c ++ 17'deki yapısal bağlamanın bu cevabın hem 1 hem de 2 noktasını geçersiz kılıp kılmadığını merak ediyorum. Öyleyse, lütfen bunun bir c ++ 17 sürümünü de ekleyin.
sandthorn

29

Bu çok geç bir cevaptır, ancak std::pairüye değişkenlerle tanımlandığı için boyutunun boş temel sınıf optimizasyonu kullanılarak optimize edilemeyeceğini ( firstve secondbiri veya her ikisi de boş sınıf olsa bile farklı adresleri işgal etmesi gerektiğini) unutmayın. Bu second_type, hizalama gereksinimleri ne olursa olsun daha da şiddetlendi , bu nedenle en kötü durumda sonuç std::pair, temelde olması gerekenin iki katı boyutta olacaktır.

std::tupleyalnızca yardımcı işlevler aracılığıyla erişime izin verir, bu nedenle, biri veya diğeri boşsa, ek yükten tasarruf ederek her iki türden de türetilmesi mümkündür. GCC'nin uygulaması, en azından, kesinlikle bunu yapıyor ... Bunu doğrulamak için başlıkları karıştırabilirsiniz, ancak bu da kanıt olarak var.


4
Elbette, C ++ 20'nin[[no_unique_address]]std::pair dezavantajını ortadan kaldırması gerekir .
Deduplicator

"std :: tuple yalnızca yardımcı işlevler aracılığıyla erişime izin verir" veya C ++ 17 yapılandırılmış bağlar. Ne yazık ki bu kadar çok makul C ++ cevabı bugünlerde bu kadar çabuk güncelliğini yitiriyor. :-(
cosimo193

29

Bir std::tupleadı daha uzundur (fazladan bir karakter). Bu karakterlerin çoğu sağ el ile yazılır, çoğu insan için yazması çok daha kolaydır.

Bununla birlikte, std::pairyalnızca iki değere sahip olabilir - sıfır, bir, üç veya daha fazla olamaz. İKİ değer. Bununla birlikte, bir demet değerlerin sayısı üzerinde neredeyse hiçbir anlamsal sınırlamaya sahip değildir. Bu std::pairnedenle, aslında bir değer çifti belirtmek istiyorsanız kullanmak için daha doğru, güvenli bir türdür.


20
LOL! Nasıl yazıldığını düşünmeniz harika! Muhtemelen "çift" i "tuple" dan% 20 daha hızlı yazdığımı belirtmek isterim. Bunun nedeni ellerimin her karakteri alternatif olarak yazmasıdır, yani. RHS: p, LHS: a, RHS: i, LHS: r. En azından benim için bunu yapmayı daha kolay buluyorum! - ama yine de +1 alırsınız!
Richard Corden

15
" Bu nedenle, bir std :: pair, gerçekten bir değer çifti belirtmek istiyorsanız kullanmak için daha doğru, güvenli bir türdür. " Daha güvenli veya "doğru" değildir, yalnızca (tartışmalı olarak) niyet daha doğrudan.
ildjarn

1
@Arafangion: std::tuple<>aynı zamanda tür açısından güvenlidir (nasıl olamaz?) Ve 2anlamsal olarak pair.
ildjarn

1
" Bir std :: çifti, bu nedenle, daha doğru, güvenli bir türdür " Ve sanırım herhangi bir İngilizce konuşanlar "çift" ve "iki" yi eşanlamlı olarak düşünecektir. : -]
ildjarn

5
@ildjam: Burada saçları bölüyoruz, ama hayır, tamamen eş anlamlı değiller . "İki ayakkabı" derken, "Her ikisi de sol ayakkabı olabilecek iki ayakkabı" mı demek istediniz, yoksa "Bir çift ayakkabı" mı demek istiyorsunuz (Biri her zaman sol, diğeri her zaman sağdır) ?
Arafangion 02

9

C ++ 17 ile, iki öğeli hem çift hem de tuple'dan veri okumak için aynı arabirimi kullanabileceğinizi unutmayın.

auto [a, b] = FunctionToReturnPairOrTuple();

Kullanmaya gerek yok get<>:)


3

Değeri ne olursa olsun, std :: tuple'ın GDB çıktısını okumayı çok daha zor buluyorum. Açıkçası, 2'den fazla değere ihtiyacınız varsa, std :: pair çalışmayacaktır, ancak bunu yapıların lehine bir nokta olarak görüyorum.


Bu yüzden onları derslerde kullandığımda brüt satırı std::get<0>(tupleName)bir alıcıya sarıyorum; GetX()okuması çok daha kolay ve kısadır. Size bir yapmayı unutursanız o küçük dezavantajı vardır constbunun gibi aptalca şeyler yapabiliriz yöntem birisi: GetX() = 20;.
Casey
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.