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.