Otomatik dönüş tipi şablon ve belirsizlik


20

Aşırı yüklenmiş bir şablon işlevi var:

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;
}

Eğer böyle çağırırsam:

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

her şey mükemmel çalışıyor, ama

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

belirsiz çağrıya neden olur.

Neden int ve OK ile diğer türlerde böyle?


4
Bence… .... Derleyicinin gördüğü gibi: ile int, typename RTveya belirtiyor typename T1musunuz? Yana 4da olduğu int, ya olabilir. İle double, 4gelmez doğrudan türüyle eşleşmesi doubleikinci aşırı yük tercih edilir, böylece.
ChrisMM

Bu bana biraz tehlikeli görünüyor çünkü dönüş türüne aşırı yükleniyorsunuz, ancak farklı miktarda parametreye sahip şablonlarla.
Borgleader

Yanıtlar:


25

RTçıkarılamaz, bu nedenle sağlanmadığında yalnızca template<typename T1, typename T2> auto overMax(T1 a, T2 b)çağrılabilir.

Bir şablon bağımsız değişkeni (kısmen) sağladığınızda, her iki yöntem de uygulanabilir,

ancak argümana bağlı olarak, kişi daha iyi bir aday olabilir:

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

    Her ikisi de overMax<double, int, double>ve overMax<double, double>uygulanabilir.
    Ama overMax<double, int, double>tam eşleşme olduğunu
    oysa overMax<double, double>gerektirir intiçin doubledönüşüm.

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

    Her ikisi de overMax<int, int, double>ve overMax<int, double>uygulanabilir.
    Ama ikisi de daha iyi bir eşleşme ya da daha uzman değil, bu yüzden çağrı belirsiz.


neden ikisi de daha iyi değil? Yumruk durumunda Max <int> (4, 7.2); dönüşümünü neden olur 7.2 için int . İkinci durumda, başlangıçta çift olan döndürülen sonuç, açık <int> nedeniyle int'e dönüştürülecek mi?
amplifikatör

1
@amplifikatör: overMax<int>(4, 7.2)ilk durumda T1=int(sağlandı), T2=double(çıkartıldı) ve ikinci durumda RT=int(sağlandı), T1=int, T2=double(çıkartıldı) olacaktır. İçeriğin her iki yöntemle ilgili tanımı, aşırı yükü seçmek için kullanılmaz.
Jarod42

benim için ikinci durum uygundur, çünkü birincisi için dönüş türü dönüşümü vardır ve ikincisi için hiç dönüşüm yoktur, değil mi?
amplifikatör

hmmm ... dönüş türü dönüşümü rol oynamıyor ... sonra, evet, her iki çağrı da bu açıdan eşdeğer
amplifikatör
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.