Saya membuka halaman ini tetapi saya tidak bisa mendapatkan alasan yang sama. Di sana disebutkan itu
"lebih bijaksana untuk tidak mengembalikan nilai sama sekali dan meminta klien menggunakan front () untuk memeriksa nilai di depan antrean"
Tapi memeriksa elemen dari front () juga membutuhkan elemen itu untuk disalin di lvalue. Misalnya di segmen kode ini
std::queue<int> myqueue;
int myint;
int result;
std::cin >> myint;
myqueue.push (myint);
/ * di sini sementara akan dibuat di kanan atas yang akan ditetapkan ke hasil, dan jika dikembalikan dengan referensi maka hasil akan dianggap tidak valid setelah operasi pop * /
result = myqueue.front(); //result.
std::cout << ' ' << result;
myqueue.pop();
pada baris kelima objek cout pertama membuat salinan myqueue.front () kemudian menetapkan itu ke hasil. Jadi, apa bedanya, fungsi pop bisa melakukan hal yang sama.
void std::queue::pop();
).front()
juga mengharuskan elemen itu disalin di lvalue" - tidak, tidak.front
mengembalikan referensi, bukan nilai. Anda dapat memeriksa nilai yang diacunya tanpa menyalinnya.pop()
. Jika Anda menggunakanstd::queue<T, std::list<T>>
maka tidak ada kekhawatiran tentang referensi yang diberikanfront()
tidak valid oleh apush()
. Tetapi Anda harus mengetahui pola penggunaan Anda dan harus mendokumentasikan batasan Anda.Jawaban:
Itu memang bisa melakukan hal yang sama. Alasannya tidak, adalah karena pop yang mengembalikan elemen yang muncul tidak aman jika ada pengecualian (harus mengembalikan berdasarkan nilai dan dengan demikian membuat salinan).
Pertimbangkan skenario ini (dengan implementasi pop yang naif / dibuat-buat, untuk mengilustrasikan maksud saya):
Jika konstruktor salinan T melempar saat kembali, Anda telah mengubah status antrian (
top_position
dalam implementasi naif saya) dan elemen dihapus dari antrian (dan tidak dikembalikan). Untuk semua maksud dan tujuan (tidak peduli bagaimana Anda menangkap pengecualian dalam kode klien) elemen di bagian atas antrian hilang.Implementasi ini juga tidak efisien jika Anda tidak membutuhkan nilai yang muncul (yaitu membuat salinan elemen yang tidak akan digunakan siapa pun).
Ini dapat diimplementasikan dengan aman dan efisien, dengan dua operasi terpisah (
void pop
danconst T& front()
).sumber
pop
? itu cukup kontra-intuitif. Itu bisa diberi namadrop
, dan kemudian jelas bagi semua orang bahwa itu tidak memunculkan elemen, tetapi malah menjatuhkannya ...pop
tidak mengembalikan apa pun. Lihat misalnya di wikipedia .Halaman yang telah Anda tautkan untuk menjawab pertanyaan Anda.
Mengutip seluruh bagian yang relevan:
C ++ dirancang dengan mempertimbangkan efisiensi, melebihi jumlah baris kode yang harus ditulis oleh programmer.
sumber
pop
yang mengembalikan nilai.pop tidak dapat mengembalikan referensi ke nilai yang dihapus, karena sedang dihapus dari struktur data, jadi apa referensi yang harus dirujuk? Itu bisa dikembalikan dengan nilai, tetapi bagaimana jika hasil pop tidak disimpan di mana pun? Kemudian waktu terbuang untuk menyalin nilai yang tidak perlu.
sumber
pop
pengembalian dan tindakan pengembalian dapat mengakibatkan pengecualian. Itu jelas harus menghapus elemen sebelum mengembalikannya, dan kemudian jika sesuatu melempar elemen itu mungkin hilang secara permanen.value_type
konstruktor pemindahan nothrow, tetapi antarmuka antrian akan berbeda bergantung pada jenis objek yang Anda simpan di dalamnya, yang tidak akan membantu.Dengan implementasi saat ini, ini valid:
Jika pop mengembalikan referensi, seperti ini:
Kemudian kode berikut bisa macet, karena referensi tidak valid lagi:
Di sisi lain, jika itu akan mengembalikan nilai secara langsung:
Kemudian Anda perlu menyalin agar kode ini berfungsi, yang kurang efisien:
sumber
Mulai dari C ++ 11 dimungkinkan untuk mengarsipkan perilaku yang diinginkan menggunakan semantik bergerak. Suka
pop_and_move
. Jadi copy konstruktor tidak akan dipanggil, dan kinerja akan bergantung pada konstruktor move saja.sumber
pop
pengecualian menjadi aman.Anda benar-benar dapat melakukan ini:
Atau, jika Anda menginginkan nilai dalam variabel, gunakan referensi:
Di samping itu: kata 'lebih masuk akal' adalah bentuk subjektif dari 'kami melihat pola penggunaan dan menemukan lebih banyak kebutuhan untuk pemisahan'. (Yakinlah: bahasa C ++ tidak berkembang begitu saja ...)
sumber
Saya pikir solusi terbaik adalah menambahkan sesuatu seperti
dimana nilai akan menerima nilai yang muncul.
Keuntungannya adalah dapat diimplementasikan dengan menggunakan operator penugasan pindah, sementara menggunakan front + pop akan membuat salinan.
sumber