Automatische Rückgabe des Vorlagentyps und der Mehrdeutigkeit

20

Ich habe eine überladene Vorlagenfunktion:

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

Wenn ich es so nenne:

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

alles funktioniert perfekt, aber

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

verursacht mehrdeutige Anrufe.

Warum ist es so mit int und OK welche anderen Typen?

Verstärker
quelle
4
Ich denke ... ... Der Compiler sieht das so: intGeben Sie das typename RToder das an typename T1? Da 4ist auch ein int, könnte es auch sein. Mit double, 4nicht direkt den Typ entsprechen doublewird die zweite Überlast bevorzugt, so.
ChrisMM
Das sieht für mich etwas zwielichtig aus, weil Sie den Rückgabetyp irgendwie überladen, aber mit Vorlagen, die unterschiedliche Parameter haben.
Borgleader

Antworten:

25

RTist nicht ableitbar, kann also nur aufgerufen werden, wenn es nicht bereitgestellt wird template<typename T1, typename T2> auto overMax(T1 a, T2 b).

Wenn Sie (teilweise) ein Vorlagenargument angeben, sind beide Methoden realisierbar.

aber je nach Argument kann man ein besserer Kandidat sein:

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

    Beides overMax<double, int, double>und overMax<double, double>sind lebensfähig.
    Aber overMax<double, int, double>ist genau passend
    während overMax<double, double>erfordert intzu doubleKonvertierung.

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

    Beides overMax<int, int, double>und overMax<int, double>sind lebensfähig.
    Aber weder ist eine bessere Übereinstimmung noch spezialisierter, so dass der Anruf mehrdeutig ist.

Jarod42
quelle
warum ist keiner von ihnen viel besser? Habe ich recht, dass im ersten Fall overMax <int> (4, 7.2); würde eine Konvertierung von 7.2 in int verursachen . Und im zweiten Fall würde das zurückgegebene Ergebnis, das anfänglich doppelt ist , aufgrund von explizitem <int> in int konvertiert werden ?
Verstärker
1
@amplifier: overMax<int>(4, 7.2)wäre im ersten Fall T1=int(bereitgestellt) T2=double(abgeleitet) und im zweiten Fall RT=int(bereitgestellt) T1=int, T2=double(abgeleitet). Die inhaltliche Definition beider Methoden wird nicht zur Auswahl der Überladung verwendet.
Jarod42
Für mich ist der zweite Fall geeignet, da es für den ersten eine Konvertierung vom Rückgabetyp und für den zweiten überhaupt keine Konvertierung gibt, nicht wahr?
Verstärker
hmmm ... die Konvertierung des Rückgabetyps spielt keine Rolle ... dann sind beide Aufrufe aus dieser Sicht gleichwertig
Verstärker