Dalam bidang C , fungsi std::make_pair telah menjadi terkenal sebagai kemudahan alat untuk mencipta pasangan. Walau bagaimanapun, isu pelik timbul apabila cuba menggunakan fungsi ini dengan parameter templat yang dinyatakan secara eksplisit dalam C 11. Artikel ini menyelidiki tingkah laku yang membingungkan di sebalik situasi ini.
Pertimbangkan perkara berikut coretan kod yang cuba mencipta sepasang rentetan dan integer dengan templat eksplisit hujah:
std::pair<std::string, int>& b = std::make_pair<std::string, int>(s, 7);
Daripada kejayaan kompilasi yang dijangkakan, mesej ralat samar muncul:
error: no matching function for call to 'make_pair(std::string&, int)'
Sumber ralat ini terletak pada penggunaan std::make_pair yang salah. Fungsi ini direka bentuk untuk membuat kesimpulan parameter templat berdasarkan hujah yang disediakan. Menyatakan parameter ini secara eksplisit menghalang proses inferens ini.
Pelaksanaan C 11 std::make_pair mengambil dua parameter jenis T&& dan U&&, dengan T dan U ialah parameter jenis templat . Apabila menyatakan hujah templat secara eksplisit, seperti yang dilihat dalam kod bermasalah, tiada potongan hujah berlaku. Sebaliknya, jenis yang ditentukan digantikan terus ke dalam perisytiharan templat, menghasilkan perkara berikut:
make_pair(std::string&& argT, int&& argU);
Perhatikan bahawa kedua-dua parameter dalam templat yang dinyatakan secara eksplisit ialah nilai rujukan (&&), yang hanya boleh mengikat kepada ungkapan nilai. Dalam kod yang disediakan, s ialah nilai (bukan sementara dan tidak dialihkan). Akibatnya, templat fungsi gagal padan dengan argumen, yang membawa kepada ralat penyusunan.
Apabila meninggalkan hujah templat eksplisit, pemotongan hujah berlaku. Disebabkan sifat istimewa parameter rujukan nilai dalam templat (rujukan runtuh), parameter rujukan nilai jenis A&&, dengan A ialah parameter jenis templat, boleh mengikat mana-mana jenis A. Sama ada A ialah nilai, nilai, layak atau tidak, A&& boleh mengikatnya.
Dalam kod contoh, s ialah nilai l jenis std::string dan 7 ialah rnilai jenis int. Pengkompil menyimpulkan T sebagai std::string& dan U sebagai int, membenarkan s dan 7 untuk mengikat dengan jayanya kepada jenis parameter yang disimpulkan.
Untuk mengelakkan ralat sedemikian, patuhi prinsip berikut: Jika argumen templat boleh disimpulkan daripada argumen fungsi, benarkan pengkompil melakukan potongan. Menyediakan hujah secara eksplisit selalunya tidak diperlukan dan boleh membawa kepada hasil yang tidak dijangka. Dengan memanfaatkan kuasa potongan hujah, pengaturcara boleh memudahkan kod mereka dan meningkatkan kebolehbacaannya sambil mengekalkan ketepatannya.
Atas ialah kandungan terperinci Mengapakah `std::make_pair` Gagal dengan Argumen Templat Eksplisit dalam C 11?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!