Perbedaan antara std :: pair dan std :: tuple dengan hanya dua anggota?

92

Apakah ada perbedaan antara an std::pairdan an std::tupledengan hanya dua anggota? (Selain yang jelas yang std::pairmembutuhkan dua dan hanya dua anggota dan tuplemungkin memiliki lebih atau kurang ...)

Casey
sumber

Jawaban:

86

Ada beberapa perbedaan:

  1. std::tupletidak pernah bisa dengan standar-layout (setidaknya, itu tidak diperlukan untuk menjadi oleh standar). Every std::pair<T, Y>adalah tata letak standar jika keduanya Tdan Ytata letak standar.

  2. Sedikit lebih mudah untuk mendapatkan konten dari pairfile tuple. Anda harus menggunakan panggilan fungsi dalam tuplekasus ini, sedangkan pairkasus hanya bidang anggota.

Tapi itu saja.

Nicol Bolas
sumber
5
"Sedikit lebih mudah untuk mendapatkan data dari sepasang daripada tupel. Sedikit." Saya perhatikan. : P Meskipun .firstdan .secondberguna, mereka tidak menawarkan bantuan jika anggota ketiga (atau lebih) diperlukan dalam perubahan kode. Saya perhatikan saya cenderung menggunakan std::getapa pun dalam Getters dengan cara itu saya tidak perlu mengubah semuanya, hanya tipe data dan make_pairpanggilan ke make_tuplepanggilan.
Casey
Tampaknya yang std::mapdigunakan std::pair<const Key,T>sebagai value_typegenap di C ++ 11. Di mana tepatnya tupel digunakan std::map?
nknight
@nknight: ... Saya tidak tahu mengapa saya mengatakan itu. Atau apa yang ingin saya katakan, bukan std::map.
Nicol Bolas
1
@Yakk: Um, saya tekan "." dan IDE saya menampilkan daftar anggota. Saya tidak berpikir orang membutuhkan hal itu.
Nicol Bolas
2
Saya ingin tahu apakah pengikatan terstruktur di c ++ 17 sudah membatalkan poin 1 dan 2 dari jawaban ini? Jika demikian, tambahkan juga versi c ++ 17 ini.
Sandthorn
29

Ini adalah jawaban yang sangat terlambat tetapi perhatikan bahwa, karena std::pairditentukan dengan variabel anggota, ukurannya tidak dapat dioptimalkan menggunakan pengoptimalan kelas dasar yang kosong ( firstdan secondharus menempati alamat yang berbeda, meskipun salah satu atau keduanya adalah kelas kosong). Hal ini diperburuk oleh persyaratan penyelarasan apa pun second_type, jadi dalam kasus terburuk, hasilnya std::pairpada dasarnya akan menjadi dua kali ukuran yang dibutuhkan.

std::tuplehanya mengizinkan akses melalui fungsi helper, jadi mungkin saja untuk berasal dari salah satu tipe jika salah satu atau lainnya kosong, menghemat biaya overhead. Implementasi GCC, paling tidak, pasti melakukan ini ... Anda dapat menyodok melalui header untuk memverifikasi ini, tetapi ada juga ini sebagai bukti.

Stephen Lin
sumber
4
Tentu saja, C ++ 20[[no_unique_address]] harus dihapusstd::pair kerugiannya.
Deduplicator
"std :: tuple hanya mengizinkan akses melalui fungsi helper", atau binding terstruktur C ++ 17. Sedih karena begitu banyak jawaban C ++ yang masuk akal begitu cepat ketinggalan zaman belakangan ini. :-(
cosimo193
29

Sebuah std::tuple's nama lebih panjang (satu karakter tambahan). Lebih banyak karakter yang diketik dengan tangan kanan, sehingga lebih mudah bagi kebanyakan orang untuk mengetik.

Artinya, std::pairhanya dapat memiliki dua nilai - bukan nol, satu, tiga, atau lebih. DUA nilai. Namun, tupel hampir tidak memiliki batasan semantik pada jumlah nilai. Sebuah std::pair, oleh karena itu, adalah lebih akurat, ketik jenis aman untuk digunakan jika Anda benar-benar ingin menentukan sepasang nilai-nilai.

Arafangion
sumber
20
LOL! Brilian, Anda mempertimbangkan cara pengetikannya! Saya ingin menunjukkan bahwa saya mungkin mengetik 'pair' lebih dari 20% lebih cepat daripada 'tuple'. Ini karena tangan saya mengetik setiap karakter secara bergantian, yaitu. RHS: p, LHS: a, RHS: i, LHS: r. Setidaknya bagi saya, saya merasa itu lebih mudah dilakukan! - tetapi Anda masih mendapatkan +1!
Richard Corden
15
" An std :: pair, oleh karena itu, adalah tipe yang lebih akurat, tipe aman untuk digunakan jika Anda benar-benar ingin menentukan sepasang nilai. " Ini tidak lebih aman untuk tipe atau "akurat", itu hanya (bisa dibilang) menandakan maksud lebih langsung.
ildjarn
1
@Arafangion: std::tuple<>adalah juga tipe-aman (bagaimana bisa itu tidak?), Dan 2tidak semantis berbeda dari pair.
ildjarn
1
" An std :: pair, oleh karena itu, adalah tipe yang lebih akurat, tipe aman untuk digunakan " Dan menurut saya setiap penutur bahasa Inggris akan menganggap 'pair` dan' two 'sebagai sinonim sepenuhnya. : -]
ildjarn
5
@ildjam: Kami membagi rambut di sini, tapi tidak, mereka tidak sepenuhnya sama. Saat Anda mengucapkan "dua sepatu", apakah yang Anda maksud adalah "Dua sepatu, yang bisa jadi keduanya adalah sepatu kiri", atau apakah yang Anda maksud adalah "Sepasang sepatu" (Salah satunya selalu kiri, dan yang lainnya selalu kanan) ?
Arafangion
9

Perhatikan bahwa dengan C ++ 17, seseorang dapat menggunakan antarmuka yang sama untuk membaca data dari pasangan dan tupel dengan dua elemen.

auto [a, b] = FunctionToReturnPairOrTuple();

Tidak perlu menggunakan get<>:)

bhardwajs
sumber
3

Untuk apa nilainya, saya menemukan keluaran GDB dari std :: tuple jauh lebih sulit untuk dibaca. Jelas jika Anda membutuhkan lebih dari 2 nilai maka std :: pair tidak akan berfungsi, tetapi saya menganggap ini sebagai poin yang mendukung struct.

tgoodhart
sumber
Itulah mengapa ketika saya menggunakannya di kelas-kelas saya membungkus garis kasar std::get<0>(tupleName)dengan getter; GetX()jauh lebih mudah dibaca dan lebih pendek. Ini memiliki kelemahan kecil yang jika Anda lupa untuk membuatnya menjadi constmetode seseorang bisa melakukan sesuatu yang bodoh seperti ini: GetX() = 20;.
Casey