std::is_same untuk Pencetakan Kontena Generik: Mengapa Ia Gagal dan Penyelesaian
Anda menghadapi masalah semasa cuba menulis fungsi generik untuk mencetak kedua-dua bekas tindanan dan baris gilir. Fungsi pada mulanya termasuk pernyataan bersyarat untuk menentukan jenis bekas (tindanan atau baris gilir) dan mengakses elemennya dengan sewajarnya. Walau bagaimanapun, pendekatan ini mengakibatkan ralat penyusunan disebabkan oleh perbezaan fungsi ahli antara kedua-dua jenis bekas.
Memahami Isu:
Ralat penyusunan berpunca daripada fakta bahawa cabang pernyataan if-else cuba mengakses front() pada jenis tindanan dan top() pada jenis baris gilir. Aksesori ini tidak tersedia pada jenis masing-masing, menyebabkan pengkompil mengadu. C mempunyai penaipan yang kuat, memerlukan jenis tertentu disediakan dengan fungsi ahli sepadan yang disokongnya.
Menyelesaikan Masalah:
Untuk menyelesaikan isu ini, kami perlu penyelesaian yang boleh membezakan antara jenis kontena sambil masih menyediakan akses kepada fungsi ahli khusus mereka. Berikut ialah dua penyelesaian yang mungkin:
1. Pengkhususan Separa dengan Pengakses:
Satu pendekatan ialah menggunakan pengkhususan templat separa dan mentakrifkan fungsi pengakses untuk setiap jenis bekas. Fungsi aksesori ini akan mendapatkan semula elemen atas atau hadapan seperti yang diperlukan.
<code class="cpp">template <typename Cont> struct element_accessor; template <typename T> struct element_accessor<std::stack<T>> { const T& operator()(const std::stack<T>& s) const { return s.top(); } }; template <typename T> struct element_accessor<std::queue<T>> { const T& operator()(const std::queue<T>& q) const { return q.front(); } }; template<typename Cont> void print_container(Cont& cont){ while(!cont.empty()){ auto elem = element_accessor<Cont>{}(cont); // call the accessor function std::cout << elem << '\n'; cont.pop(); } }
2. jika constexpr dengan C 17:
Jika persekitaran pembangunan anda menyokong C 17, anda boleh menggunakan pernyataan if constexpr, yang melaksanakan penilaian masa kompilasi dan membenarkan pelaksanaan bersyarat berdasarkan jenis bekas.
<code class="cpp">template<template<class> typename Cont, typename T> void print_container(Cont<T>& cont){ while(!cont.empty()){ if constexpr (std::is_same_v<Cont<T>, std::stack<T>>) std::cout << cont.top() << '\n'; else if constexpr (std::is_same_v<Cont<T>, std::queue<T>>) std::cout << cont.front() << '\n'; cont.pop(); } }</code>
Kedua-dua penyelesaian membolehkan anda menulis fungsi generik yang boleh mencetak kedua-dua bekas tindanan dan baris gilir, dengan berkesan berkongsi kod antara algoritma carian seperti DFS dan BFS.
Atas ialah kandungan terperinci Mengapa `std::is_same` Gagal Semasa Mencetak Bekas Generik?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!