multiple definition of



  • Ich verwende folgende externe Headerdatei: http://www.davekoelle.com/files/alphanum.hpp

    bisher hab ich sie einmal im Projekt verwendet (eingebunden in einer cpp) und es funktioniert wunderbar.
    Jetzt wollte ich sie an einer anderen Stelle wiederverwenden, allerdings eingebunden in einer Headerdatei, da templates im Spiel sind. Eigentlich ja kein Problem, da überall include-guards vorhanden sind.

    die Templates sehen so aus:

    template<class T>
    struct CompareAsc
    {
    	bool operator() ( const T& lhs, const T& rhs )
    	{
    		return doj::alphanum_comp( lhs, rhs ) < 0;
    	}
    };
    
    template<class T>
    struct CompareDesc
    {
    	bool operator() ( const T& lhs, const T& rhs )
    	{
    		return !CompareAsc<T>( lhs, rhs );
    	}
    };
    
    template<class T, class U, class V>
    void sortVec( std::vector<const T*>* vec, U(*func)(), const V& comp )
    {
    	std::map<U, T*, V> tempSortMap;
    	for ( typename std::vector<const T*>::iterator iter( vec->begin() ); iter != vec->end(); ++iter )
    	{
    		//...
    	}
    	//...
    }
    

    ich hoffe, der Code ist nicht allzu schlecht 🤡

    folgendes will ich damit erreichen: ich bekomme von einem anderen Teil des Programms Vektoren die vom Aufbau her zwar gleich, aber jedesmal andere Objekte beinhalten, die ich mit der oben verlinkten headerdatei sortieren will.
    Nach welchem Attribut genau die Objekte sortiert werden sollen, entscheidet der übergebene Funktionspointer (also ob jetzt nach getNummer() oder getBezeichnung() sortiert werden soll). Der letzte Parameter entscheidet, ob CompareAsc oder CompareDesc der Map als Ersatz für std:less<> übergeben werden.

    Vom Grundprinzip her sollte es eigentlich funktionieren...

    beim compilieren (bzw. genauer beim linken) kommen aber diverse "multiple definition of", die sich alle auf die alphanum.hpp beziehen (alle alphanum_comp() werden insgesamt dreimal aufgelistet) 😕
    aber sollte das durch die include-guards nicht verhindert werden?



  • Includeguards verhindern nur das mehrfache Einbinden innerhalb einer Übersetzungseinheit, bspw. wenn Du alphanum.hpp in zwei anderen Headerdateien einbindest. In mehreren Übersetzungseinheiten tut der Includeguard nichts, wäre auch fatal, da sonst ja die Deklarationen fehlen würden.

    Ich nehme an, alphanum_comp ist weder Template noch Inline? (Mögliche Lösung in dieser Frage enthalten)



  • Das Problem am header ist, wie bereits gesagt wurde, dass der Header die Implementation normaler Funktionen direkt enthält. Also entweder in hpp/cpp aufteilen oder mit den genannten Schlüsselwörtern reparieren.



  • otze schrieb:

    Das Problem am header ist, wie bereits gesagt wurde, dass der Header die Implementation normaler Funktionen direkt enthält. Also entweder in hpp/cpp aufteilen oder mit den genannten Schlüsselwörtern reparieren.

    jetzt hats geklingelt... eigentlich ja klar.
    Und nachdem ich jetzt alle als inline definiert hab, gehts plötzlich 🙂

    vielen dank euch beiden für die Hilfe



  • Wie bereits gesagt wurde: Im Header werden Funktionen mit external linkage definiert, welche weder inline noch Templates sind (Verletzung der ODR-Regeln, falls das Ding in mehrere Übersetzungseinheiten eingebunden wird). Das macht man einfach nicht.

    Anonyme Namensräume haben eigentlich in Header-Dateien auch nichts zu suchen. In diesem Fall könnte das sogar eine weitere Verletzung der ODR-Regeln sein, weil ein Funktionstemplate mit external linkage, die "anonymen" Funktionen aufrufen. Knackpunkt hier ist, dass so eine "anonyme" Funktion nicht einzigartig ist, sondern jede Übersetzungseinheit, eine eigene Version enthält (internal linkage). Das führt dann zu inkonsistenten Templatespezialisierungen über den Übersetzungseinheiten.

    Gruß,
    SP


Anmelden zum Antworten