Pengenalan
C 17 memperkenalkan if constexpr kata kunci, membenarkan kompilasi bersyarat berdasarkan pemalar masa kompilasi. Walau bagaimanapun, ralat yang tidak dijangka boleh timbul apabila menggunakan if constexpr dalam fungsi bukan templat. Artikel ini meneroka isu ini dan menyediakan penyelesaian.
Contoh Kod
Pertimbangkan kod berikut:
<code class="cpp">#include <iostream> #include <type_traits> int main() { auto value = 100; if constexpr (std::is_pointer_v<decltype(value)>) std::cout << "Ptr to " << *value << std::endl; // Error else std::cout << "Ref to " << value << std::endl; }
Ralat Penyusunan
Kod ini menjana ralat kompilasi apabila pernyataan if constexpr berada dalam fungsi utama:
main.cpp:8:32: error: invalid type argument of unary ‘*’ (have ‘int’) std::cout << "Ptr to " << *value << std::endl;
Penjelasan
Jika constexpr sahaja berfungsi dalam fungsi templat kerana ia membenarkan pengkompil untuk mengelakkan cawangan instantiating yang tidak diambil pada masa penyusunan. Pengoptimuman ini penting untuk pengaturcaraan meta templat yang cekap.
Dalam fungsi bukan templat, jika constexpr masih menilai kedua-dua cabang, walaupun jenis itu disimpulkan oleh decltype. Ini bermakna ralat dalam kod di atas disebabkan oleh percubaan untuk menyahrujuk nilai int dalam cawangan if.
Penyelesaian
Untuk menyelesaikan isu ini, anda boleh alihkan pernyataan if constexpr ke dalam fungsi templat. Contohnya:
<code class="cpp">template <typename T> void print(T value) { if constexpr (std::is_pointer_v<decltype(value)>) std::cout << "Ptr to " << *value << std::endl; else std::cout << "Ref to " << value << std::endl; } int main() { auto value = 100; print(value); }</code>
Kod yang diubah suai ini akan menyusun dan mencetak output yang dijangkakan:
Ref to 100
Atas ialah kandungan terperinci Mengapa 'jika constexpr' menyebabkan ralat dalam fungsi bukan templat dalam C 17?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!