Überladen/Spezialisieren von Template-Funktionen



  • Moin Leute!

    Ich habe in einer Template-Klasse die Funktionen

    BOOL Equals (T a, T b)
    BOOL Equals (std::string a, std::string b)
    

    Beim Kompilieren tritt die folgende Fehlermeldung auf:

    error C2535: 'BOOL MyClass<T>::Equals(T,T)' : member function already defined or declared
    

    Warum der Fehler auftritt kann ich zumindest nachvollziehen (T kann ja auch vom Typ std::string sein), aber wie muss ich die Funktion überladen, damit bei Variablen vom Typ std::string die zweite Funktion aufgerufen wird?

    Ich hab's auch mit einer Spezialisierung versucht:

    template <typename T> BOOL Equals (T a, T b) 
    template <class T> BOOL Equals (std::string a, std::string b)
    

    Dann bekomme ich allerdings die folgende Fehlermeldung:

    error C2678: binary '==' : no operator found which takes a left-hand operand of type 'std::basic_string<_Elem,_Traits,_Ax>' (or there is no acceptable conversion)
    

    Die Klassen, die den "=="-Operator nicht entsprechend implementiert haben anzupassen kommt leider nicht in Frage, daher brauche ich eine andere Lösung. Kann mir da jemand helfen?



  • - in C++ haben wir den Typen bool
    - Du zeigst zu wenig Code
    - Deine "Spezialisierungen" sehen nicht wie Spezialisierungen aus



  • Die Funktionen beinhalten nicht wirklich interessanten Code, aber ich kann ihn der Vollständigkeit halber ja noch mal posten.

    // Template-Fuktion zum Vergleichen von Werten
    	template <typename T> bool Equals (T a, T b) 
    	{
    		return a == b;
    	}
    
    	template <typename T> bool Equals (std::string a, std::string b) 
    	{
    		bool result = false;
    		if (a.compare(b) == 0) 
    		{
    			result = true;
    		}
    		return result;
    	}
    

    Wie müsste die richtige Spezialisierung denn dann aussehen? Ungefähr so?

    // Template-Fuktion zum Vergleichen von Werten
    	template <typename T> bool Equals (T a, T b) 
    	{
    		return a == b;
    	}
    
    	template <std::string> bool Equals (std::string a, std::string b) 
    	{
    		bool result = false;
    		if (a.compare(b) == 0) 
    		{
    			result = true;
    		}
    		return result;
    	}
    


  • Ich habe zuerst an SFINAE gedacht, dann an Überladung, und schliesslich gemerkt, dass das alles unnötig ist, weil std::string auch einen operator== unterstützt.

    Davon abgesehen frage ich mich wirklich, warum viele Leute den maximal komplizierten Weg wählen.

    bool result = false; 
            if (a.compare(b) == 0) 
            { 
                result = true; 
            } 
            return result;
    

    ->

    return a.compare(b) == 0;
    

    Aber wie gesagt: Hier reicht eine Funktion.



  • Templatefunktionen sollte man nicht spezialisieren: http://www.gotw.ca/publications/mill17.htm



  • Ganz davon abgesehen:

    1. Hat es sein Grund das nicht der Typ bool für die Rückgabe verwendet wird (Was ist BOOL?).
    2. Wäre es nicht sinnvoller (auch wenn dies bei den Basisdatentypen vielleicht einen kleinen Overhead erzeugt) statt "By Value" lieber auf konstante Referenzen umzustellen, oder sollen wirklich immer Kopien zum vergleichen erzeugt werden?

    bool Equals (T const & a, T const & b);
    

Log in to reply