-
December 21st, 2012, 01:15 AM
#1
Unresolved Externals for Template class.
Code:
// declaration
template<class T>
class GetValue
{
void Initialize(std::string fileName);
};
// definition
template<class T>
void GetValue<T>::Initialize(std::string fileName)
{
}
// inheritance
class GetD3DXVECTOR3 : public GetValue<D3DXVECTOR3>
{
};
I understood that GetValue<D3DXVECTOR3>::Initialize was not defined. How can I reuse the GetValue::Initialize method in every derived classes from GetValue, such as GetD3DXVECTOR3, GetD3DXMATRIX, GetOpenGLVector3 etc
Thanks
Jack
-
December 21st, 2012, 05:56 PM
#2
Re: Unresolved Externals for Template class.
The only issue i see in the code you posted is that GetValue<T>::Initialize() is not public (or protected) but that shouldn't cause an undefined error, so are you using some "friend-based" mechanism to get to the method or what exactly are you doing? Can you post more code?
-
December 21st, 2012, 09:04 PM
#3
Re: Unresolved Externals for Template class.
Oh no, there still link time problem
At first blush, I have put a public identifier in there.
Code:
#include <xercesc/dom/DOM.hpp>
#include <xercesc/dom/DOMDocument.hpp>
#include <xercesc/dom/DOMDocumentType.hpp>
#include <xercesc/dom/DOMElement.hpp>
#include <xercesc/dom/DOMImplementation.hpp>
#include <xercesc/dom/DOMImplementationLS.hpp>
#include <xercesc/dom/DOMNodeIterator.hpp>
#include <xercesc/dom/DOMNodeList.hpp>
#include <xercesc/dom/DOMText.hpp>
#include <xercesc/parsers/XercesDOMParser.hpp>
#include <xercesc/util/XMLUni.hpp>
#include <string>
#include <d3dx9.h>
using namespace std;
using namespace xercesc;
template<class T>
class GetValue
{
public:
GetValue() { }
~GetValue() { }
virtual T get(std::string element) = 0;
void Initialize(std::string filename);
protected:
xercesc::XercesDOMParser* m_Parser;
xercesc::DOMDocument *doc;
XMLCh* TAG_root;
};
class GetD3DXVECTOR3 : public GetValue<D3DXVECTOR3>
{
public:
GetD3DXVECTOR3() { }
~GetD3DXVECTOR3() { }
public:
D3DXVECTOR3 get(std::string element);
private:
D3DXVECTOR3 m_Vec;
};
class GetD3DXMATRIX : public GetValue<D3DXMATRIX>
{
public:
GetD3DXMATRIX() { }
~GetD3DXMATRIX() { }
public:
D3DXMATRIX get(std::string element);
private:
D3DXMATRIX m_Mat;
};
Code:
#include <Stdafx.h>
#include <d3dx9.h>
#include <iostream>
#include <sstream>
#include <boost/lexical_cast.hpp>
#include "Parser.h"
using namespace std;
#define X(str) XStr(str).unicodeForm()
template<class T>
float ToFloat(const T& value)
{
float f = boost::lexical_cast<float>(value);
return f;
}
template<class T>
void GetValue<T>::Initialize(std::string filename)
{
try
{
XMLPlatformUtils::Initialize(); // Initialize Xerces infrastructure
}
catch( XMLException& e )
{
char* message = XMLString::transcode( e.getMessage() );
cerr << "XML toolkit initialization error: " << message << endl;
XMLString::release( &message );
// throw exception here to return ERROR_XERCES_INIT
}
// Tags and attributes used in XML file.
// Can't call transcode till after Xerces Initialize()
TAG_root = XMLString::transcode(X("BPS-Simulation-Format"));
m_Parser = new XercesDOMParser;
m_Parser->parse(filename.c_str());
doc = m_Parser->getDocument();
}
D3DXVECTOR3 GetD3DXVECTOR3::get(std::string element)
{
try
{
DOMElement* elementRoot = doc->getDocumentElement();
if( !elementRoot ) throw(std::runtime_error( "empty XML document" ));
// Parse XML file for tags of interest: "ApplicationSettings"
// Look one level nested within "root". (child of root)
DOMNodeList* children = elementRoot->getChildNodes();
const XMLSize_t nodeCount = children->getLength();
for( XMLSize_t xx = 0; xx < nodeCount; ++xx )
{
DOMNode* currentNode = children->item(xx);
if( currentNode->getNodeType() && // true is not NULL
currentNode->getNodeType() == DOMNode::ELEMENT_NODE ) // is element
{
// Found node which is an Element. Re-cast node as element
DOMElement* currentElement
= dynamic_cast< xercesc::DOMElement* >( currentNode );
XMLCh buff[100];
XMLString::transcode(element.c_str(), buff, 99);
if( XMLString::equals(currentElement->getTagName(), buff))
{
// Already tested node as type element and of name "ApplicationSettings".
// Read attributes of element "ApplicationSettings".
const XMLCh* xmlch_X
= currentElement->getAttribute(L"X");
m_Vec.x = ToFloat(XMLString::transcode(xmlch_X));
const XMLCh* xmlch_Y
= currentElement->getAttribute(L"Y");
m_Vec.y = ToFloat(XMLString::transcode(xmlch_Y));
const XMLCh* xmlch_Z
= currentElement->getAttribute(L"Z");
m_Vec.z = ToFloat(XMLString::transcode(xmlch_Z));
break; // Data found. No need to look at other elements in tree.
}
}
}
}
catch( xercesc::XMLException& e )
{
char* message = xercesc::XMLString::transcode( e.getMessage() );
std::ostringstream errBuf;
errBuf << "Error parsing file: " << message << flush;
XMLString::release( &message, xercesc_3_1::XMLPlatformUtils::fgMemoryManager );
}
return m_Vec;
}
D3DXMATRIX GetD3DXMATRIX::get(std::string element)
{
try
{
DOMElement* elementRoot = doc->getDocumentElement();
if( !elementRoot ) throw(std::runtime_error( "empty XML document" ));
// Parse XML file for tags of interest: "ApplicationSettings"
// Look one level nested within "root". (child of root)
DOMNodeList* children = elementRoot->getChildNodes();
const XMLSize_t nodeCount = children->getLength();
for( XMLSize_t xx = 0; xx < nodeCount; ++xx )
{
DOMNode* currentNode = children->item(xx);
if( currentNode->getNodeType() && // true is not NULL
currentNode->getNodeType() == DOMNode::ELEMENT_NODE ) // is element
{
// Found node which is an Element. Re-cast node as element
DOMElement* currentElement
= dynamic_cast< xercesc::DOMElement* >( currentNode );
XMLCh buff[100];
XMLString::transcode(element.c_str(), buff, 99);
if( XMLString::equals(currentElement->getTagName(), buff))
{
// Already tested node as type element and of name "ApplicationSettings".
// Read attributes of element "ApplicationSettings".
const XMLCh* xmlch_11
= currentElement->getAttribute(L"_11");
m_Mat.m[0][0] = ToFloat(XMLString::transcode(xmlch_11));
const XMLCh* xmlch_12
= currentElement->getAttribute(L"_12");
m_Mat.m[0][1] = ToFloat(XMLString::transcode(xmlch_12));
const XMLCh* xmlch_13
= currentElement->getAttribute(L"_12");
m_Mat.m[0][2] = ToFloat(XMLString::transcode(xmlch_13));
const XMLCh* xmlch_14
= currentElement->getAttribute(L"_13");
m_Mat.m[0][3] = ToFloat(XMLString::transcode(xmlch_14));
////
const XMLCh* xmlch_21
= currentElement->getAttribute(L"_21");
m_Mat.m[1][0] = ToFloat(XMLString::transcode(xmlch_21));
const XMLCh* xmlch_22
= currentElement->getAttribute(L"_22");
m_Mat.m[1][1] = ToFloat(XMLString::transcode(xmlch_11));
const XMLCh* xmlch_23
= currentElement->getAttribute(L"_23");
m_Mat.m[1][2] = ToFloat(XMLString::transcode(xmlch_23));
const XMLCh* xmlch_24
= currentElement->getAttribute(L"_24");
m_Mat.m[1][3] = ToFloat(XMLString::transcode(xmlch_24));
//
const XMLCh* xmlch_31
= currentElement->getAttribute(L"_31");
m_Mat.m[2][0] = ToFloat(XMLString::transcode(xmlch_31));
const XMLCh* xmlch_32
= currentElement->getAttribute(L"_32");
m_Mat.m[2][1] = ToFloat(XMLString::transcode(xmlch_32));
const XMLCh* xmlch_33
= currentElement->getAttribute(L"_33");
m_Mat.m[2][2] = ToFloat(XMLString::transcode(xmlch_33));
const XMLCh* xmlch_34
= currentElement->getAttribute(L"_34");
m_Mat.m[2][3] = ToFloat(XMLString::transcode(xmlch_34));
//
const XMLCh* xmlch_41
= currentElement->getAttribute(L"_41");
m_Mat.m[3][0] = ToFloat(XMLString::transcode(xmlch_41));
const XMLCh* xmlch_42
= currentElement->getAttribute(L"_42");
m_Mat.m[3][1] = ToFloat(XMLString::transcode(xmlch_42));
const XMLCh* xmlch_43
= currentElement->getAttribute(L"_43");
m_Mat.m[3][2] = ToFloat(XMLString::transcode(xmlch_43));
const XMLCh* xmlch_44
= currentElement->getAttribute(L"_44");
m_Mat.m[3][3] = ToFloat(XMLString::transcode(xmlch_44));
break; // Data found. No need to look at other elements in tree.
}
}
}
}
catch( xercesc::XMLException& e )
{
char* message = xercesc::XMLString::transcode( e.getMessage() );
std::ostringstream errBuf;
errBuf << "Error parsing file: " << message << flush;
XMLString::release( &message, xercesc_3_1::XMLPlatformUtils::fgMemoryManager );
}
return m_Mat;
}
Last edited by lucky6969b; December 21st, 2012 at 11:25 PM.
-
December 22nd, 2012, 06:21 AM
#4
Re: Unresolved Externals for Template class.
Move the definition of Initialize into the header (that contains the declaration of GetValue<T>) and it should work, see this faq for more information: http://www.parashift.com/c++-faq/tem...n-vs-decl.html
-
December 22nd, 2012, 06:21 PM
#5
Re: Unresolved Externals for Template class.
Thanks Zlatomir,
That does the job nicely. Have a great Chrismtas holiday.
Jack
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|