[C++] Template-Spezialisierung führt zu Linkerfehlern

Programmiersprachen, APIs, Bibliotheken, Open Source Engines, Debugging, Quellcode Fehler und alles was mit praktischer Programmierung zu tun hat.
Antworten
Benutzeravatar
Schrompf
Moderator
Beiträge: 5161
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas
Wohnort: Dresden
Kontaktdaten:

[C++] Template-Spezialisierung führt zu Linkerfehlern

Beitrag von Schrompf »

Moin Leute,

ich habe mir Helferfunktionen geschrieben, um aus XML-Dateien mit wenig Code Daten rausziehen zu können. Ein typisches XML-File sieht so aus:

Code: Alles auswählen

<Objekt>
  <Dings name="bla" id="5" />
  <Blubb wert="7.2" />
</Objekt>
Um sowas einfach zu lesen, habe ich unter Anderem folgende Funktionen erfunden.

Code: Alles auswählen

  /// Liest das benannte Attribut aus dem gegebenen Element und gibt dessen Inhalt als gewünschten Typ zurück
  template <typename Typ> 
  Typ LiesAttribut( const TiXmlElement* pElm, const char* pAttrName)
  {
    const char* attr = pElm->Attribute( pAttrName);
    if( !attr)
      WirfAusnahme( boost::str( boost::format( "Attribut \"%s\" erwartet in Element \"%s\".") % pAttrName % pElm->ValueStr()));

    Typ erg;
    try
    {
      erg = boost::lexical_cast<Typ>( attr);
    } catch( boost::bad_lexical_cast& ex)
    {
      WirfAusnahme( boost::str( boost::format( "Attribut \"%s\" in Node \"%s\" konnte nicht in Zieltyp konvertiert werden - %s") % pAttrName % pElm->Value() % ex.what()));
    }

    return erg;
  }

  /// Template-Spezialisierung für std::string - braucht keine Konvertierung in Zieltyp
  template <> 
  inline std::string LiesAttribut( const TiXmlElement* pElm, const char* pAttrName)
  {
    const char* attr = pElm->Attribute( pAttrName);
    if( !attr)
      WirfAusnahme( boost::str( boost::format( "Attribut \"%s\" erwartet in Element \"%s\".") % pAttrName % pElm->ValueStr()));

    return std::string( attr);
  }
Man beachte das "inline" vor der spezialisierten Template-Funktion. Warum ist das nötig? Templates müssen doch immer im Header implementiert werden. Ich meine... ich hab's jetzt gelöst, aber ich versteh's nicht. Kann da jemand ein Licht drauf werfen?
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Benutzeravatar
Aramis
Moderator
Beiträge: 1458
Registriert: 25.02.2009, 19:50
Echter Name: Alexander Gessler
Wohnort: 2016
Kontaktdaten:

Re: [C++] Template-Spezialisierung führt zu Linkerfehlern

Beitrag von Aramis »

Die Spezialisierung ist (gemaess dem Sprachstandard :-)) kein Template, sondern unterliegt den Linkage-Regeln fuer ganz normale Funktionen. Also braucht es ein inline wenn sie im Header steht um Linkerfehler wg. doppelt definierter Symbole zu vermeiden.
Benutzeravatar
Aramis
Moderator
Beiträge: 1458
Registriert: 25.02.2009, 19:50
Echter Name: Alexander Gessler
Wohnort: 2016
Kontaktdaten:

Re: [C++] Template-Spezialisierung führt zu Linkerfehlern

Beitrag von Aramis »

Ok, Nachtrag:
Templates müssen doch immer im Header implementiert werden.
Da Template-Spezialisierungen keine Templates sind, muessen sie auch nicht im Header implementiert werden. Nur ihre Deklaration muss fuer alle Uebersetzungseinheiten die das Basistemplate instanziieren erreichbar sein, sprich im Header liegen :-)
Benutzeravatar
Schrompf
Moderator
Beiträge: 5161
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas
Wohnort: Dresden
Kontaktdaten:

Re: [C++] Template-Spezialisierung führt zu Linkerfehlern

Beitrag von Schrompf »

Ah ok, das erklärt es. Danke Dir!
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Antworten