Problem mit Template-Definition
-
Hallo,
ich habe folgenden Code der unter Linux in einer Lib laufen soll. Leider mache irgend etwas falsch.#include <string.h> #include <iostream> #include <fstream> #include <string> #include <rapidxml/rapidxml_print.hpp> using namespace rapidxml; template<class Ch = char> class CParseXML { private: char *ParseText; rapidxml::xml_document<Ch> m_doc; // character type defaults to char public: CParseXML(const std::string& File) : ParseText(NULL) { if (strlen(ParseText)) Parse(ParseText); } long Parse (char *XmlString) { long RC = 0; try { m_doc.parse<parse_default>(XmlString); // 0 means default parse flags } catch (rapidxml::parse_error& ex) { std::cout << ex.what(); RC = -1; } return RC; } ~CParseXML(void) { delete [] ParseText; }; }; long ParseLicence(const char *OutStream, const std::string& SerialNumber) { CParseXML<> *pParseXML = new CParseXML<>(OutStream); if (!pParseXML) return -1; }nach:
g++ test.cpp -I. -fPIC -c -Wallbekomme ich folgendes:
dan@dev-pc-dan-linux:~/src/test$ g++ test.cpp -I. -fPIC -c -Wall test.cpp: In member function ‘long int CParseXML<Ch>::Parse(char*) [with Ch = char]’: test.cpp:21:4: instantiated from ‘CParseXML<Ch>::CParseXML(const std::string&) [with Ch = char, std::string = std::basic_string<char>]’ test.cpp:43:52: instantiated from here test.cpp:27:4: error: invalid operands of types ‘<unresolved overloaded function type>’ and ‘const int’ to binary ‘operator<’ test.cpp: In function ‘long int ParseLicence(const char*, const std::string&)’: test.cpp:45:1: warning: control reaches end of non-void function dan@dev-pc-dan-linux:~/src/test$Ich verwende RapidXML 1.13 und den GCC 4.5.2
Hat jemand eine Ahnung warum g++ denkt, dass < in der Zeile 27 ein Operator ist?Danke für Eure Hilfe schonmal im Voraus,
Christian
-
Meintest du nicht
m_doc.Parse<parse_default>(XmlString);?
Der Compiler erkennt parse nicht und denkt danach kommt ein < Operator.
-
cdannebe schrieb:
m_doc.parse<parse_default>(XmlString);m_doc hängt von einem template-parameter ab, der compiler weiß zu dem Zeitpunkt noch nichts genaueres über parse, du musst ihm also sagen, dass parse ein template ist:
m_doc.template parse<parse_default>(XmlString);
-
jokester_ schrieb:
cdannebe schrieb:
m_doc.parse<parse_default>(XmlString);m_doc hängt von einem template-parameter ab, der compiler weiß zu dem Zeitpunkt noch nichts genaueres über parse, du musst ihm also sagen, dass parse ein template ist:
m_doc.template parse<parse_default>(XmlString);Danke jokester_ für Deine schnelle Antwort. Hat geklappt.
Weist Du auch warum der Code mit VS2010 funktioniert hat?Christian
PS: Ein Danke auch an [Rewind] für die Mühen.
-
Deine Initialisierung von ParseText im Konstruktor ist irgendwie komisch.
Die Dreierregel hast Du auch verletzt.Der Compiler beschwert sich aber deswegen:
cdannebe schrieb:
[b]template<class Ch = char>[/b] class CParseXML { private: char *ParseText; rapidxml::xml_document<[b]Ch[/b]> [b]m_doc[/b]; public: ::: long Parse (char *XmlString) { long RC = 0; try { [b]m_doc[/b].parse<parse_default>(XmlString); } ::: } ::: };Ob das < hinter parse jetzt der kleiner-als-Operator ist oder eine Spitze Klammer für Templateparameter hängt jetzt davon ab, was parse eigentlich ist. Da m_doc vom Templateparameter Ch abhängt, kann der Compiler beim "ersten Durchgang" (also vor dem Instanziieren) nicht wissen, was parse wirlich ist. Der Standard fordert, dass der Programmierer hier sagen muss, ob es sich um ein Funktions-Template handelt. Richtig sieht das dann so aus:
m_doc.template parse<parse_default>(XmlString);Der Microsoft Compiler verzeiht die ein fehlendes template, weil er sich das Template vor dem Instanziieren gar nicht richtig anguckt und er gar nicht wissen will, was das < da zu bedeuten hat.