Jenis dan ambiguitas pengembalian otomatis


20

Saya memiliki fungsi template yang kelebihan beban:

template<typename T1, typename T2>
auto overMax(T1 a, T2 b)
{
    std::cout << __FUNCSIG__ << std::endl;

    return b < a ? a : b;
}

template<typename RT, typename T1, typename T2>
RT overMax(T1 a, T2 b)
{
    std::cout << __FUNCSIG__ << std::endl;

    return b < a ? a : b;
}

Jika saya menyebutnya seperti ini:

auto a = overMax(4, 7.2); // uses first template
auto b = overMax<double>(4, 7.2); // uses second template

semuanya bekerja dengan sempurna, tetapi

auto c = overMax<int>(4, 7.2); // error

menyebabkan panggilan ambigu.

Mengapa begitu dengan int , dan OK jenis apa yang lain?


4
Saya pikir ... .... Cara kompiler melihatnya, adalah: dengan int, apakah Anda menentukan typename RTatau typename T1? Karena 4juga merupakan int, bisa jadi keduanya. Dengan double, 4tidak secara langsung cocok dengan jenisnya double, jadi kelebihan kedua lebih disukai.
— ChrisMM

Ini terlihat agak cerdik bagi saya karena Anda semacam kelebihan pada tipe kembali tetapi dengan template yang memiliki jumlah parameter yang berbeda.
— Borgleader

Jawaban:


25

RTtidak dapat dikurangkan, jadi ketika tidak menyediakannya, hanya template<typename T1, typename T2> auto overMax(T1 a, T2 b)dapat dipanggil.

Ketika Anda (sebagian) memberikan satu argumen templat, kedua metode tersebut layak,

tetapi tergantung dari argumen, seseorang dapat menjadi kandidat yang lebih baik:

  • Untuk auto b = overMax<double>(4, 7.2); // uses second template

    Keduanya overMax<double, int, double>dan overMax<double, double>layak.
    Tapi overMax<double, int, double>ini sama persis
    sedangkan overMax<double, double>membutuhkan intuntuk doublekonversi.

  • Untuk auto c = overMax<int>(4, 7.2); // Ambiguous call

    Keduanya overMax<int, int, double>dan overMax<int, double>layak.
    Tetapi tidak ada pasangan yang lebih baik atau lebih terspesialisasi, sehingga panggilannya ambigu.


mengapa tak satu pun dari mereka yang lebih baik? Apakah saya benar bahwa dalam kasus pertama overMax <int> (4, 7.2); akan menyebabkan konversi 7,2 ke int . Dan dalam kasus kedua hasil yang dikembalikan, yang awalnya ganda , akan dikonversi ke int karena <int> eksplisit ?
— penguat

1
@amplifier: overMax<int>(4, 7.2)akan dalam kasus pertama T1=int(disediakan), T2=double(disimpulkan) dan dalam kasus kedua RT=int(disediakan), T1=int, T2=double(disimpulkan). Definisi konten dari kedua metode tidak digunakan untuk memilih kelebihan muatan.
— Jarod42

bagi saya, kasus kedua cocok, karena ada konversi tipe pengembalian untuk yang pertama dan tidak ada konversi sama sekali untuk yang kedua, bukan?
— penguat

hmmm ... konversi tipe kembali tidak berperan ... maka, ya, kedua panggilan setara dari sudut pandang ini
— penguat
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.