?
Wenn der Compiler sich das aus den Parametern, die Du der Funktion übergibst, selbst ableiten kann dann muss man das nicht mit angeben. Das klappt aber nicht immer: Gegenbeispiele:
template<class R, class T, class U>
R add(T t, U u)
{
R r = t;
t += u;
return r;
}
…
add<double>(2,3);
(Man muss R angeben, T und U können automatisch bestimmt werden)
template<class T>
T add2(T t, T u)
{
return t+u;
}
…
add(2,3.3); // Klappt nicht!
denn nach dem ersten Parameter würde T=int gelten. Aber dem zweiten Parameter zufolge käme der Compiler auf T=double. In so einem Fall schlägt die "template argument deduction" einfach fehl. Wenn Du allerdings add<double>(2,2.3) oder add(2.0,3.0) schreibst, klappt es wieder. Das Misslingen der "Template Argument Deduction" ist übrigens kein "harter" Fehler. Das Funktionstemplate wird dann einfach ignoriert. Nur wenn keine passende Funktion übrig bleibt, meckert der Compiler. Manchmal kann es sinvoll sein, "TAD" für einen Parameter auszuschalten. Das geht über einen Trick:
template<class T> struct identity{typedef T type;};
template<class T>
struct punkt
{
T x, y;
};
// template<class T>
// punkt<T> operator*(punkt<T> const& p, T faktor);
template<class T>
punkt<T> operator*(punkt<T> const& p, typename identity<T>::type faktor);
// ^^^^^^^^^^^^^^^^^^^^^^^^^^
Obwohl aus identity<T>::type wieder T selbst wird, stellt es einen sogenannten "non-deduced context" dar. Das heißt, der Compiler verwendet diesen Parameter nicht, um T rauszubekommen.
kk