Mengapa tampaknya tidak ada yang menggunakan tupel di C ++, baik Perpustakaan Boost Tuple atau perpustakaan standar untuk TR1? Saya telah membaca banyak kode C ++, dan sangat jarang saya melihat penggunaan tupel, tetapi saya sering melihat banyak tempat di mana tupel akan memecahkan banyak masalah (biasanya mengembalikan banyak nilai dari fungsi).
Tuple memungkinkan Anda melakukan semua jenis hal keren seperti ini:
tie(a,b) = make_tuple(b,a); //swap a and b
Itu pasti lebih baik dari ini:
temp=a;
a=b;
b=temp;
Tentu saja Anda selalu bisa melakukan ini:
swap(a,b);
Tetapi bagaimana jika Anda ingin merotasi tiga nilai? Anda dapat melakukan ini dengan tupel:
tie(a,b,c) = make_tuple(b,c,a);
Tupel juga mempermudah pengembalian beberapa variabel dari suatu fungsi, yang mungkin merupakan kasus yang jauh lebih umum daripada menukar nilai. Menggunakan referensi untuk mengembalikan nilai tentu tidak terlalu elegan.
Apakah ada kekurangan besar pada tupel yang tidak saya pikirkan? Jika tidak, mengapa jarang digunakan? Apakah mereka lebih lambat? Atau hanya karena orang tidak terbiasa dengan mereka? Apakah ide yang bagus untuk menggunakan tupel?
a = a ^ b; b = a ^ b; a = a ^ b;
Jawaban:
Karena itu belum standar. Apa pun yang tidak standar memiliki rintangan yang jauh lebih tinggi. Potongan Boost telah menjadi populer karena programmer berteriak-teriak untuk itu. (hash_map melompat ke pikiran). Tapi sementara tuple berguna, itu bukan kemenangan yang luar biasa dan jelas sehingga orang-orang peduli dengannya.
sumber
Jawaban sinisnya adalah banyak orang memprogram dalam C ++, tetapi tidak memahami dan / atau menggunakan fungsionalitas tingkat yang lebih tinggi. Kadang-kadang karena mereka tidak diperbolehkan, tetapi banyak yang tidak mencoba (atau bahkan mengerti).
Sebagai contoh non-boost: berapa banyak orang yang menggunakan fungsionalitas yang ditemukan
<algorithm>
?Dengan kata lain, banyak programmer C ++ hanyalah programmer C yang menggunakan kompiler C ++, dan mungkin
std::vector
danstd::list
. Itulah salah satu alasan mengapa penggunaanboost::tuple
tidak lebih umum.sumber
Sintaks C ++ tuple bisa lebih bertele-tele daripada yang diinginkan kebanyakan orang.
Mempertimbangkan:
Jadi jika Anda ingin menggunakan tupel secara ekstensif, Anda bisa mendapatkan tuple typedef di mana-mana atau Anda mendapatkan nama tipe yang sangat panjang di mana-mana. Saya suka tuple. Saya menggunakannya bila perlu. Tapi biasanya terbatas pada beberapa situasi, seperti indeks elemen-N atau saat menggunakan multimaps untuk mengikat pasangan iterator rentang. Dan biasanya dalam ruang lingkup yang sangat terbatas.
Semuanya terlihat sangat jelek dan meretas jika dibandingkan dengan sesuatu seperti Haskell atau Python. Ketika C ++ 0x sampai di sini dan kita mendapatkan kata kunci 'otomatis' tupel akan mulai terlihat jauh lebih menarik.
Kegunaan tupel berbanding terbalik dengan jumlah penekanan tombol yang diperlukan untuk mendeklarasikan, mengemas, dan mengekstraknya.
sumber
Bagi saya, itu kebiasaan, tangan ke bawah: Tuple tidak memecahkan masalah baru bagi saya, hanya beberapa yang sudah bisa saya tangani dengan baik. Bertukar nilai masih terasa lebih mudah dengan cara lama - dan, yang lebih penting, saya tidak terlalu memikirkan cara menukar "lebih baik". Ini cukup bagus apa adanya.
Secara pribadi, saya tidak berpikir tupel adalah solusi yang bagus untuk mengembalikan banyak nilai - kedengarannya seperti pekerjaan untuk
struct
s.sumber
Tetapi bagaimana jika Anda ingin merotasi tiga nilai?
OK, jadi dengan 4 nilai dll, akhirnya n-tuple menjadi kode yang lebih sedikit dari n-1 swap. Dan dengan default swap, ini melakukan 6 tugas, bukan 4 yang Anda miliki jika Anda menerapkan template tiga siklus sendiri, meskipun saya berharap kompilator akan menyelesaikannya untuk tipe sederhana.
Anda dapat menemukan skenario di mana swap tidak berguna atau tidak sesuai, misalnya:
agak canggung untuk dibuka.
Intinya adalah, bagaimanapun, ada cara yang diketahui untuk menangani situasi paling umum yang baik untuk tupel, dan karenanya tidak ada urgensi yang besar untuk mengambil tupel. Jika tidak ada yang lain, saya tidak yakin bahwa:
tidak membuat 6 salinan, membuatnya sama sekali tidak cocok untuk beberapa jenis (koleksi menjadi yang paling jelas). Jangan ragu untuk meyakinkan saya bahwa tuple adalah ide yang bagus untuk tipe "besar", dengan mengatakan ini tidak begitu :-)
Untuk mengembalikan beberapa nilai, tupel sempurna jika nilainya memiliki tipe yang tidak kompatibel, tetapi beberapa orang tidak menyukainya jika pemanggil bisa mendapatkannya dalam urutan yang salah. Beberapa orang sama sekali tidak menyukai beberapa nilai pengembalian, dan tidak ingin mendorong penggunaannya dengan membuatnya lebih mudah. Beberapa orang lebih suka struktur bernama untuk parameter masuk dan keluar, dan mungkin tidak dapat dibujuk dengan tongkat baseball untuk menggunakan tupel. Tidak ada perhitungan rasa.
sumber
Seperti yang ditunjukkan banyak orang, tupel tidak begitu berguna seperti fitur lainnya.
Gimmick yang bertukar dan berputar hanyalah tipuan. Mereka benar-benar membingungkan bagi mereka yang belum pernah melihatnya sebelumnya, dan karena hampir semua orang, tipu muslihat ini hanyalah praktik rekayasa perangkat lunak yang buruk.
Mengembalikan beberapa nilai menggunakan tupel jauh lebih sedikit mendokumentasikan diri sendiri daripada alternatif - mengembalikan tipe bernama atau menggunakan referensi bernama. Tanpa pendokumentasian sendiri ini, mudah untuk mengacaukan urutan nilai yang dikembalikan, jika keduanya dapat diubah satu sama lain, dan tidak lebih bijak.
sumber
Tidak semua orang dapat menggunakan boost, dan TR1 belum tersedia secara luas.
sumber
Saat menggunakan C ++ pada sistem tersemat, menarik pustaka Boost menjadi rumit. Mereka berpasangan satu sama lain, sehingga ukuran perpustakaan bertambah. Anda mengembalikan struktur data atau menggunakan penerusan parameter alih-alih tupel. Ketika mengembalikan tupel dengan Python, struktur data berada dalam urutan dan jenis nilai yang dikembalikan itu tidak eksplisit.
sumber
Anda jarang melihatnya karena kode yang dirancang dengan baik biasanya tidak membutuhkannya- tidak banyak kasus di alam liar di mana menggunakan struct anonim lebih baik daripada menggunakan yang bernama. Karena semua tupel benar-benar mewakili sebuah struct anonim, kebanyakan pembuat kode dalam banyak situasi hanya pergi dengan yang asli.
Katakanlah kita memiliki fungsi "f" di mana pengembalian tupel mungkin masuk akal. Sebagai aturan umum, fungsi seperti itu biasanya cukup rumit sehingga bisa gagal.
Jika "f" DAPAT gagal, Anda memerlukan pengembalian status - bagaimanapun juga, Anda tidak ingin pemanggil harus memeriksa setiap parameter untuk mendeteksi kegagalan. "f" mungkin cocok dengan pola:
Itu tidak bagus, tapi lihat betapa jelek alternatifnya. Perhatikan bahwa saya masih membutuhkan nilai status, tetapi kodenya tidak lagi dapat dibaca dan tidak lebih pendek. Mungkin lebih lambat juga, karena saya mengeluarkan biaya 1 salinan dengan tupel.
Sisi negatif lainnya yang signifikan tersembunyi di sini- dengan "ReturnInts" saya dapat menambahkan kembali "f" dengan memodifikasi "ReturnInts" TANPA MENGUBAH INTERFACE "f". Solusi tupel tidak menawarkan fitur penting itu, yang menjadikannya jawaban inferior untuk kode library apa pun.
sumber
using std::tuple;
dan hanya menggunakantuple
dalam kode.tuple
membuat kode kurang dapat dibaca, tidak lebih. Sebagian besar kode saat ini memiliki jumlah simbol yang sangat besar di dalamnya - melihatstd::tuple
dengan jelas apa sebenarnya kode itu.Tentu saja tuple dapat berguna, tetapi seperti yang telah disebutkan, ada sedikit overhead dan satu atau dua rintangan yang harus Anda lewati sebelum Anda benar-benar dapat menggunakannya.
Jika program Anda secara konsisten menemukan tempat di mana Anda perlu mengembalikan beberapa nilai atau menukar beberapa nilai, mungkin ada baiknya menggunakan rute tuple, tetapi sebaliknya terkadang lebih mudah untuk melakukan sesuatu dengan cara klasik.
Secara umum, tidak semua orang sudah menginstal Boost, dan saya pasti tidak akan repot-repot mengunduhnya dan mengonfigurasi direktori include saya untuk bekerja dengannya hanya untuk fasilitas tuple-nya. Saya pikir Anda akan menemukan bahwa orang-orang yang sudah menggunakan Boost lebih cenderung menemukan penggunaan tuple dalam program mereka daripada pengguna non-Boost, dan migran dari bahasa lain (yang muncul dalam pikiran Python) lebih cenderung kesal karena kurangnya tupel di C ++ daripada mempelajari metode menambahkan dukungan tupel.
sumber
Karena penyimpanan data
std::tuple
memiliki karakteristik terburuk dari astruct
dan larik; semua akses didasarkan pada posisi ke-n tetapi seseorang tidak dapat melakukan iterasi melaluituple
afor
lingkaran.Jadi jika elemen dalam
tuple
secara konseptual adalah sebuah array, saya akan menggunakan sebuah array dan jika elemen tersebut bukan sebuah array secara konseptual, sebuah struct (yang memiliki nama elemen) lebih dapat dipelihara. (a.lastname
lebih jelas daripadastd::get<1>(a)
).Ini meninggalkan transformasi yang disebutkan oleh OP sebagai satu-satunya usecase yang layak untuk tupel.
sumber
Saya merasa banyak yang menggunakan Boost.Any dan Boost.Variant (dengan beberapa teknik) daripada Boost.Tuple.
sumber