Linkerror bei Template Funktion
-
Hallo,
ich habe einen merkwürdigen Linkerror bei einer Template Funktion und so langsam bin ich mit meinem Latein am Ende - vielleicht hat ja hier noch jemand eine Idee.
Hintergrund:
Ziel ist es eine Template Funktion zu schreiben die sowohl std::liststd::string wie auch std::vectorstd::string als Parameter akzeptiert.
Diese sieht dann so aus:
// implode // // ----------------------------------------------------------------------------- template<class T> std::string Implode(const T& inStringList, const std::string& inGlue) { std::string output; typename T::const_iterator iter; int16 element = 0; for(iter = inStringList.begin(); iter != inStringList.end(); ++iter) { ++element; output += *iter; if(element <= inStringList.size() - 1) output += inGlue; } return output; }Die Funktion wird auch ohne Fehler kompiliert, nur dann bekomme ich Linkerrors und zwar an den Stellen wo ich die Funktion verwende:
Link Error : undefined: 'std::string CDCX::Implode<std::list<std::string, std::allocatorstd::string > >(const std::list<std::string, std::allocatorstd::string >&, const std::string&)' (code)
Referenced from 'CDataLookupASCIIDlg::ProcessASCIIDependenciesFile(HeaderFieldFocus*)' in D_DataLookupASCIIDlg.cpp
Referenced from 'CDataLookupASCIIDlg::XDDoVerb(xdwapparamrec*)' in D_DataLookupASCIIDlg.cppLink Error : undefined: 'std::string CDCX::Implode<std::vector<std::string, std::allocatorstd::string > >(const std::vector<std::string, std::allocatorstd::string >&, const std::string&)' (code)
Referenced from 'CDataLookupASCIIDlg::ProcessASCIIDependenciesFile(HeaderFieldFocus*)' in D_DataLookupASCIIDlg.cpp
Referenced from 'CDataLookupHTTPDlg::XDDoVerb(xdwapparamrec*)' in D_DataLookupHTTPDlg.cpp
Referenced from 'CDataLookupASCIIDlg::XDDoVerb(xdwapparamrec*)' in D_DataLookupASCIIDlg.cpp
Referenced from 'CDataLookupASCIIDlg::ReadDataFile(const std::string&)' in D_DataLookupASCIIDlg.cppWobei dies hier z.B. ein möglicher Aufruf ist (Zeile 16 bzw. 18):
std::map<uint32, std::list<std::string> > fieldValueMap; std::map<uint32, std::list<std::string> >::const_iterator fieldValueIter; for(fieldValueIter = fieldValueMap.begin(); fieldValueIter != fieldValueMap.end(); ++fieldValueIter) { std::vector<std::string> oldRecords; if(setupSettings.mMultiValue) { std::string oldFieldValue; gXTP->mDXTLinkP->GetFieldValue(fieldValueIter->first, oldFieldValue); size_t numberOfRecords = CDCX::Explode(oldFieldValue, oldRecords, *(recordSeparator.c_str()), false); if(mFieldNumber < oldRecords.size()) oldRecords.at(mFieldNumber) = CDCX::Implode(fieldValueIter->second, fieldSeparator); else oldRecords.push_back(CDCX::Implode(fieldValueIter->second, fieldSeparator)); } else { oldRecords.push_back(CDCX::Implode(fieldValueIter->second, fieldSeparator)); } gXTP->mDXTLinkP->SetFieldValue(fieldValueIter->first, CDCX::Implode(oldRecords, recordSeparator)); }MacDisein
-
*tief durchatmet* Um die Template-Methode anlegen zu können, muß der Compiler ihren Inhalt (Definition) und ihre Instanziierung (Verwendung) gleichzeitig sehen. Darum gehören Template-Implementierungen (grundsätzlich) in den Header.
(beim Übersetzen der Implode() weiß der Compiler nicht, ob er später die Implode<vector<string> >, Implode<list<int> > oder Implode<Hundekuchen> benötigen wird, also kontrolliert er nur auf syntaktische Fehler - beim Übersetzen des Hauptprogramms weiß er nicht, wie die Funktion aufgebaut ist)
-
Im Header war die Funktion auch als Template Funktion definiert, ich hatte erwartet, dass das ausreichen würde.
template<class T> std::string Implode(const T& inStringList, const std::string& inGlue)Jetzt wo auch die Implementierung im Header ist gibt es auch keine Linkerrors mehr - wieder was dazugelernt.
Thema kann geschlossen werden!
Vielen Dank für die super schnelle Hilfe!
MacDisein