that
ModeratorHoffnungsloser Optimist
|
Hallo an alle, gestern hatte ein Arbeitskollege ein seltsames Problem, vielleicht kennt sich ja wer von euch mit C++ aus. #include <iostream>
class A {};
class B : public A {};
template<typename T>
void f(T) { std::cout << "f(T)" << std::endl; }
void f(A*) { std::cout << "f(A*)" << std::endl; }
int main()
{
int x = 42;
A a;
B b;
f(x);
f(&a);
f(&b);
return 0;
}
Unerwarterweise gibt das Programm als letzte Zeile "f(T)" aus statt "f(A*)", es dürfte also die Template Vorrang haben gegenüber der Basisklasse. Erstaunlich ist, dass es aber das Gewünschte tut, wenn man die Template auf f(T& ändert. Das Problem ist also im Prinzip gelöst - aber wer kanns erklären?
|
ica
hmm
|
vielleicht diese seite hier: http://www.gotw.ca/publications/mill17.htmedit: ok, nachdems ichs jetzt mal ausprobiert hab und den gesamten output gesehen hab versteh ich erst was du meinst also ich kenn den standard nicht, aber für mich machts schon sinn. er schaut sich die A* funktion an und sieht, dass es nicht der gleiche typ ist. dann schaut er sich die T funktion an die eben den gleichen typ hat -> ergo nimmt er die. das "erstaunliche" verstehe ich nicht ganz. T& wäre ja eine referenz, die wird er nicht nehmen weils nicht passt. die T* zieht er nach wie vor der A* vor.
Bearbeitet von ica am 20.09.2008, 20:40
|
Nico
former person of interest
|
early-/latebinding issue maybe?
|
that
ModeratorHoffnungsloser Optimist
|
das "erstaunliche" verstehe ich nicht ganz. T& wäre ja eine referenz, die wird er nicht nehmen weils nicht passt. die T* zieht er nach wie vor der A* vor. Wenn du f(x) aufrufst, dann kann das entweder f(X) oder f(X& sein - der Aufruf sieht gleich aus. Daher fand ichs erstaunlich, dass das einen Unterschied macht. Aber ich hab die hinterlistigen Details von Referenzen nie völlig durchschaut. Jedenfalls dürfte es wirklich so sein, dass sich der Compiler erst für Template oder nicht entscheidet und erst dann genauer schaut, welcher Typ jetzt am besten passt.
|
Vivo
Dreamworker
|
Das Problem ist also im Prinzip gelöst - aber wer kanns erklären? Das gelöst musst du unter Anführungszeichen setzen ... Das funktioniert nur, weil du die Funktion f(T& im Template mit B* aufrufst -> und das ist nicht gültig ... Würdst du statt f(T& ein f(T*) nehmen, dann wäre das wieder ein korrekter Aufruf und es würde wieder "nicht funktionieren" ... Demnach ist deine Aussage aus deinem 1. Post richtig: Template vor Basisklasse
|