Templates



  • hey,
    ich hab schon wieder eine Frage...
    ich hab hier folgendes kleines Programm:

    #include <iostream>
    using namespace std;
    
    template <class T> T max(T x, T y) {
    	if (x>y)
    		return x;
    	else
    		return y;
    }
    
    int main() {
    	int a=5;
    	int b=8;
    	double c=12.3;
    	double d=18.7;
    	cout << max(a,b) << "\n";
    	cout << max(c,d) << "\n";
    	return 0;
    }
    

    Wenn ich das kompilieren will, dann funktioniert das nicht - aber ich versteh einfach nicht, wo das Problem liegt...

    Das hier spuckt der compiler aus:

    test3.cpp: In function ‘int main()’:
    test3.cpp:16: error: call of overloaded ‘max(int&, int&)’ is ambiguous
    test3.cpp:4: note: candidates are: T max(T, T) [with T = int]
    /usr/include/c++/4.0.0/bits/stl_algobase.h:206: note:                 const _Tp& std::max(const _Tp&, const _Tp&) [with _Tp = int]
    test3.cpp:17: error: call of overloaded ‘max(double&, double&)’ is ambiguous
    test3.cpp:4: note: candidates are: T max(T, T) [with T = double]
    /usr/include/c++/4.0.0/bits/stl_algobase.h:206: note:                 const _Tp& std::max(const _Tp&, const _Tp&) [with _Tp = double]
    

    Kann mir da einer helfen?



  • Ja, dank deinem using namespace std gibts in dem Scope zwei Funktionen max. Benutze ::max oder nimm das using namespace std weg. 🙂



  • max gibts auch im namespace std::
    Du ziehst Dir mit using namespace std alles aus std:: in den globalen Namensraum. Daher gibts Konflikte.

    #include <iostream>
    //using namespace std; <- kein using namespace!
    
    template <class T> T max(T x, T y) {
    	if (x>y)
    		return x;
    	else
    		return y;
    }
    
    int main() {
    	int a=5;
    	int b=8;
    	double c=12.3;
    	double d=18.7;
    	std::cout << max(a,b) << "\n"; //explizit std:: mit angeben
    	std::cout << max(c,d) << "\n"; //dito
    	return 0;
    }
    

    Alternativ: Deine Funktion anders nennen, z.B. myMax



  • hmm ja ihr habt Recht - mit den Änderungen funktioniert das Programm. Aber ich verstehs irgendwie nicht wirklich.

    Ich habe mir mit dem template doch eine allgemeine Funktion max gebastelt. Und jetzt ruf ich sie weiter unten auf mit max(a,b). Dann müsste er doch die Funktion aufrufen und die Werte ausspucken. Wieso muss dann der Name geändert werden?

    Komischerweise hab ich grad gemerkt, dass das Programm auch funktioniert, wenn ich sowas hinschreibe:

    template <class T> T dasisteinkomischertest(T x,T y) {
    

    wieso kann das denn funktionieren?? 😕



  • Wanderfalke schrieb:

    hmm ja ihr habt Recht - mit den Änderungen funktioniert das Programm. Aber ich verstehs irgendwie nicht wirklich.

    Was verstehst du nicht? Der Compiler findet nunmal 2 verschiedene max-Funktionen:
    Da du using namespace std verwendet hast sieht er einmal die std::max und einmal dein max, und kann nicht wissen welche du aufrufen willst.

    Und logischerweise funktioniert dein Programm wenn du deine Funktion ausdokumentierst, da er dann keinen Namenskonflikt hat, und gleich die max-Funktion der Standardbibliothek aufruft.

    cu André



  • also kann man eigentlich sagen, dass es ziemlich bescheuert war, die Funktion max zu nennen. Die Folge davon, dass ich da ::max hingeschrieben hab, war doch nur, dass er die max-Funktion aus der Standardbibliothek genommen hat und das template links liegen gelassen hat, oder?



  • Wanderfalke schrieb:

    also kann man eigentlich sagen, dass es ziemlich bescheuert war, die Funktion max zu nennen...

    Nein, eher das du using namespace eingesetzt hast, ohne dir die Folgen zu verinnerlichen. Wenn ich eine Funktion schreiben würde, die einen Maximalwert zurückliefert, würde ich diese auch max nennen, doch läge sie in einem anderen Namensraum.

    using namespace ist solange ganz okay, solange man Mehrdeutigkeiten ausschließen kann (und man es nicht im Header verwendet, da es sonst global gilt...).



  • Wanderfalke schrieb:

    Die Folge davon, dass ich da ::max hingeschrieben hab, war doch nur, dass er die max-Funktion aus der Standardbibliothek genommen hat und das template links liegen gelassen hat, oder?

    Nein, ::max ist die Funktion auf globaler Ebene (also Deine). Die aus der Standardbibliothek wäre std::max.

    Nur ist durch das using namespace std die Funktion std::max ebenfalls im globalen Namensraum bekannt gemacht worden. Damit kann "max" (ohne Namespace-Angabe) entweder ::max oder std::max sein, der Compiler weiss nicht, welche von beiden.



  • ah ok - vielen Dank! 🙂


Anmelden zum Antworten