Apa yang saya katakan di bawah (di bawah POST LAMA ) harus benar untuk gelar, tetapi masalah sebenarnya dengan ini, bahwa SFINAE digunakan secara salah, maka saya tidak yakin lagi bahwa ini adalah bug di gcc.
Deklarasi alias harus selalu berhasil, Anda tidak dapat SFINAE di sana, karena itu bukan deklarasi kelas atau fungsi atau spesialisasi (yang masuk akal, karena Anda tidak dapat mengkhususkan alias). Jika deklarasi alias tidak berhasil, programnya salah bentuk. Oleh karena itu kompilator dapat berasumsi bahwa itu tidak akan pernah sampai pada kasus bahwa deklarasi alias tidak berhasil sampai Anda memaksanya untuk membuat contoh seperti template.
Oleh karena itu sangat dapat diterima bagi kompiler untuk berpikir bahwa sfinae_v_t<T,...>
itu selaluT
, karena itu akan terjadi, ketika program tidak terbentuk dengan buruk. Oleh karena itu ia akan melihat, bahwa dalam semua kasus di mana program tidak terbentuk dengan buruk, spesialisasi parsial tidak mengkhususkan dan dengan demikian ia akan memberi tahu Anda bahwa ini adalah dibentuk buruk. (Itulah yang dilakukan dentang).
Saya tidak berpikir bahwa kompiler terpaksa melakukan ini. Dan jika tidak, dan hanya berpikir "Oke,sfinae_v_t
ada beberapa jenis, apa pun.", Maka tidak jelas bahwa ini adalah deklarasi ulang. Jadi saya pikir sampai kita instantiate salah satunya tidak ada yang salah dengan tidak melempar kesalahan.
Tetapi ketika kita instantiate itu harus ada masalah bahwa kita memiliki deklarasi ulang atau bahwa program tersebut tidak terbentuk karena std::enable_if
, tergantung pada argumen template. GCC harus mengambil setidaknya satu dari mereka tetapi tidak melakukannya.
Ini juga sama sekali tidak berlaku untuk contoh yang lebih mudah tanpa std::enable_if
. Jadi saya masih berpikir ini adalah bug di GCC, tapi saya cukup berpikiran bahwa saya tidak bisa mengatakan itu dengan pasti lagi. Saya hanya akan mengatakan, seseorang harus melaporkan itu sebagai bug dan membiarkan orang-orang dari gcc memikirkannya.
POST LAMA
Ini adalah bug di gcc. Standar memberi kita aturan untuk mengonversi templat kelas di templat fungsi. Satu templat kelas lebih khusus daripada yang lain jika fungsinya datang sebelum yang lain dalam urutan templat fungsi parsial.
Saya membuat fungsi di sini dan sekarang klaim gcc bahwa memanggil mereka ambigu, maka itu juga harus mengatakan bahwa templat kelas sama-sama ditentukan.
Catatan: Membaca standar dengan seksama, kompiler di kepala saya setuju dengan dentang.