Saya menggunakan pustaka C ++ ( strf ) yang, di suatu tempat di dalamnya, memiliki kode berikut:
namespace strf {
template <typename ForwardIt>
inline auto range(ForwardIt begin, ForwardIt end) { /* ... */ }
template <typename Range, typename CharT>
inline auto range(const Range& range, const CharT* sep) { /* ... */ }
}
Sekarang, saya ingin menggunakan strf::range<const char*>(some_char_ptr, some_char_ptr + some_length)
kode saya. Tetapi jika saya melakukannya, saya mendapatkan kesalahan berikut (dengan NVCC CUDA 10.1):
error: more than one instance of overloaded function "strf::range" matches the argument list:
function template "auto strf::range(ForwardIt, ForwardIt)"
function template "auto strf::range(const Range &, const CharT *)"
argument types are: (util::constexpr_string::const_iterator, util::constexpr_string::const_iterator)
The perpustakaan kode mungkin dapat diubah untuk menghindari ini (misalnya menggunakan:
inline auto range(const typename std::enable_if<not std::is_pointer<typename std::remove_cv<Range>::type>::value, Range &>::type range, const CharT* sep)
untuk memastikan Range
bukan pointer); tapi saya tidak bisa melakukan perubahan itu sekarang. Sebagai gantinya, saya ingin menunjukkan ke kompiler bahwa saya benar-benar bermaksud hanya memiliki satu argumen templat, bukan satu yang ditentukan dan satu lagi dideduksi.
Bisakah saya melakukan itu?
Akan menghargai jawaban untuk C ++ 11 dan C ++ 14; C ++ 17 jawaban yang melibatkan panduan deduksi kurang relevan tetapi jika Anda punya, silakan posting (untuk versi NVCC mendatang ...)
Pembaruan: Perpustakaan strf itu sendiri telah diperbarui untuk menghindari situasi ini, tetapi pertanyaannya tetap seperti yang ditanyakan.
char*
tetapi bukankah itu bukan solusi?Jawaban:
Kemudian panggil
range1
alih-alihstrf::range
.range1_ptr<T>(...)
selalu dapat digunakan untuk secara eksplisit memanggil templat yang mengambil satu argumen templat, tetapi tidak melakukan deduksi dari argumen.range1
mereplikasi deduksi daristrf::range
templat asli .Ini berfungsi, karena [temp.deduct.funcaddr] / 1 mengatakan bahwa pengurangan argumen templat ketika mengambil alamat suatu fungsi tanpa tipe target konversi dilakukan pada setiap templat fungsi kandidat seolah-olah parameter dan daftar argumen dari panggilan hipotetis adalah kosong. Jadi argumen templat kedua tidak dapat disimpulkan untuk kelebihan kedua dengan dua parameter templat. Satu-satunya kandidat yang tersisa adalah kelebihan beban pertama, yang akan dipilih sebagai target dari pointer fungsi.
Selama tidak ada templat fungsi kandidat kedua yang template-id yang valid dengan hanya satu argumen dapat dibentuk,
range1_ptr
selalu dapat digunakan untuk memanggil templat fungsi mengambil satu argumen dengan jelas. Kalau tidak, instantiasirange1_ptr
akan memberikan kesalahan karena ambiguitas.sumber
strf::range<T>
?pretty_please_with_sugar_on_top()
? ... C ++ kadang-kadang bisa sangat aneh ...Bagaimana dengan melewati sebuah
using
?sumber
range()
versi pertama yang kompatibel dengantpf
; kasus lain bisa berbeda.tfp x = &strf::range<char const *>;
); dengan cara ini saya kira Anda memiliki solusi umum, hampir setara dengan kacang walnutSebuah solusi adalah
1) pertama-tama, Anda harus menentukan tipe untuk argumen kedua, misalnya
(char *)(some_char_ptr + some_length)
2) tidak digunakan
const
untuk keduanya, ini bekerja dengan baik:Anda dapat mencoba menggantinya
(char *)
dengan(const char *)
di kiri ATAU di kanan, itu masih berfungsi.sumber
const
data.