Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > undefined external template fn?

Reply
Thread Tools

undefined external template fn?

 
 
.rhavin grobert
Guest
Posts: n/a
 
      06-11-2008
Hi group....



i have the following class....
__________________________________________________ ___
// QSharedReg.hpp

typedef unsigned __int64 QUAD;
using namespace boost;

template<class T> struct _SQSRI {
QUAD qID;
shared_ptr<T> pItem;
};


template <class T> class CQSharedReg {
public:
CQSharedReg();
virtual ~CQSharedReg();
inline UINT Count() const {return m_vector.size();};
shared_ptr<T> const Get(QUAD qID) const;
shared_ptr<T> const GetByIdx(UINT nIdx) const;
shared_ptr<T> Register(QUAD qID);
bool Unregister(QUAD qID);

private:
std::vector<_SQSRI<T> > m_vector;
};
__________________________________________________ ______

....and the following implementation.....
__________________________________________________ ______
// QSharedReg.cpp

//-----------------------------------------------------------------------------
template <class T> CQSharedReg<T>::CQSharedReg() {}

//-----------------------------------------------------------------------------
template <class T> CQSharedReg<T>::~CQSharedReg() {}

//-----------------------------------------------------------------------------
template <class T> shared_ptr<T> const CQSharedReg<T>::Get(QUAD qID)
const {
register UINT nCnt = Count();
_SQSRI<T> const* psqri;
while (nCnt-->0) {
psqri = &m_vector[nCnt];
if (psqri == NULL)
continue;
if (psqri->qID != qID)
continue;
return psqri->pItem;
}
shared_ptr<T> none;
return none;
}

//-----------------------------------------------------------------------------
template <class T> shared_ptr<T> const CQSharedReg<T>::GetByIdx(UINT
nIdx) const {
if (nIdx >= m_vector.size()) {
shared_ptr<T> none;
return none;
}
return m_vector[nIdx].pItem;
}

//-----------------------------------------------------------------------------
template <class T> shared_ptr<T> CQSharedReg<T>::Register(QUAD qID) {
shared_ptr<T> pItem = (shared_ptr<T>) Get(qID);
if (pItem.get() != NULL)
return pItem;
_SQSRI<T> sqri;
sqri.pItem = new T;
sqri.qID = qID;
m_vector.push_back(sqri);
return sqri.pItem;
}

//-----------------------------------------------------------------------------
template <class T> bool CQSharedReg<T>::Unregister(QUAD qID) {
register UINT nCnt = Count();
_SQSRI<T>* psqri;
while (nCnt-->0) {
psqri = &m_vector[nCnt];
if (psqri == NULL)
continue;
if (psqri->qID != qID)
continue;
m_vector.erase(psqri);
return true;
}
return false;
}
__________________________________________________ ______

the object "QSharedReg.obj" compiles fine (is there anything to
compile!?) but when i instatiate it in another class (here in class
CQElement using) ....

__________________________________________________ ______
// from QElement.hpp
CQSharedReg<CQDetail> m_rDetails;

// from QElement.cpp

UINT nCnt = m_rDetails.Count();
shared_ptr<CQDetail> pDetail3 = m_rDetails.Register(3);
nCnt = m_rDetails.Count();
shared_ptr<CQDetail> pDetail5 = m_rDetails.Register(5);
nCnt = m_rDetails.Count();
if (pDetail5.get() != NULL) {
shared_ptr<CQDetail> pDetail1 = m_rDetails.Register(1);
nCnt = m_rDetails.Count();
}
nCnt = m_rDetails.Count();


__________________________________________________ ______

....., i get the following error (name-mangling skipped): ...

QElement.obj : error LNK2001: unresolved external symbol "public:
virtual __thiscall CQSharedReg<class CQDetail>::~CQSharedReg<class
CQDetail>(void)"
QElement.obj : error LNK2001: unresolved external symbol "public:
class boost::shared_ptr<class CQDetail> __thiscall CQSharedReg<class
CQDetail>::Register(unsigned __int64)"
QElement.obj : error LNK2001: unresolved external symbol "public:
__thiscall CQSharedReg<class CQDetail>::CQSharedReg<class
CQDetail>(void)"

....so if i interpret it right, the linker tries for example to find a
function
CQSharedReg<class CQDetail>::~CQSharedReg<class CQDetail>(void)
but that function IS defined...

Any help apreciated, TIA, -.rhavin
 
Reply With Quote
 
 
 
 
suresh shenoy
Guest
Posts: n/a
 
      06-11-2008
On Jun 11, 8:26*am, ".rhavin grobert" <(E-Mail Removed)> wrote:
> Hi group....
>
> i have the following class....
> __________________________________________________ ___
> // QSharedReg.hpp
>
> typedef unsigned __int64 QUAD;
> using namespace boost;
>
> template<class T> struct _SQSRI {
> * * * * QUAD * * * * * qID;
> * * * * shared_ptr<T> *pItem;
>
> };
>
> template <class T> class CQSharedReg {
> public:
> * * * * CQSharedReg();
> * * * * virtual ~CQSharedReg();
> * * * * inline UINT * * * * Count() const {return m_vector..size();};
> * * * * shared_ptr<T> const Get(QUAD qID) const;
> * * * * shared_ptr<T> const GetByIdx(UINT nIdx) const;
> * * * * shared_ptr<T> * * * Register(QUAD qID);
> * * * * bool * * * * * * * *Unregister(QUAD qID);
>
> private:
> * * * * std::vector<_SQSRI<T> > m_vector;};
>
> __________________________________________________ ______
>
> ...and the following implementation.....
> __________________________________________________ ______
> // QSharedReg.cpp
>
> //-------------------------------------------------------------------------*----
> template <class T> CQSharedReg<T>::CQSharedReg() {}
>
> //-------------------------------------------------------------------------*----
> template <class T> CQSharedReg<T>::~CQSharedReg() {}
>
> //-------------------------------------------------------------------------*----
> template <class T> shared_ptr<T> const CQSharedReg<T>::Get(QUAD qID)
> const {
> * * * * register UINT nCnt = Count();
> * * * * _SQSRI<T> const* psqri;
> * * * * while (nCnt-->0) {
> * * * * * * * * psqri = &m_vector[nCnt];
> * * * * * * * * if (psqri == NULL)
> * * * * * * * * * * * * continue;
> * * * * * * * * if (psqri->qID != qID)
> * * * * * * * * * * * * continue;
> * * * * * * * * return psqri->pItem;
> * * * * }
> * * * * shared_ptr<T> none;
> * * * * return none;
>
> }
>
> //-------------------------------------------------------------------------*----
> template <class T> shared_ptr<T> const CQSharedReg<T>::GetByIdx(UINT
> nIdx) const {
> * * * * if (nIdx >= m_vector.size()) {
> * * * * * * * * shared_ptr<T> none;
> * * * * * * * * return none;
> * * * * }
> * * * * return m_vector[nIdx].pItem;
>
> }
>
> //-------------------------------------------------------------------------*----
> template <class T> shared_ptr<T> CQSharedReg<T>::Register(QUAD qID) {
> * * * * shared_ptr<T> pItem = (shared_ptr<T>) Get(qID);
> * * * * if (pItem.get() != NULL)
> * * * * * * * * return pItem;
> * * * * _SQSRI<T> sqri;
> * * * * sqri.pItem = new T;
> * * * * sqri.qID * = qID;
> * * * * m_vector.push_back(sqri);
> * * * * return sqri.pItem;
>
> }
>
> //-------------------------------------------------------------------------*----
> template <class T> bool CQSharedReg<T>::Unregister(QUAD qID) {
> * * * * register UINT nCnt = Count();
> * * * * _SQSRI<T>* psqri;
> * * * * while (nCnt-->0) {
> * * * * * * * * psqri = &m_vector[nCnt];
> * * * * * * * * if (psqri == NULL)
> * * * * * * * * * * * * continue;
> * * * * * * * * if (psqri->qID != qID)
> * * * * * * * * * * * * continue;
> * * * * * * * * m_vector.erase(psqri);
> * * * * * * * * return true;
> * * * * }
> * * * * return false;}
>
> __________________________________________________ ______
>
> the object "QSharedReg.obj" compiles fine (is there anything to
> compile!?) but when i instatiate it in another class (here in class
> CQElement using) ....
>
> __________________________________________________ ______
> // from QElement.hpp
> * * * * CQSharedReg<CQDetail> m_rDetails;
>
> // from QElement.cpp
>
> * * * * UINT nCnt = m_rDetails.Count();
> * * * * shared_ptr<CQDetail> pDetail3 = m_rDetails.Register(3);
> * * * * nCnt = m_rDetails.Count();
> * * * * shared_ptr<CQDetail> pDetail5 = m_rDetails.Register(5);
> * * * * nCnt = m_rDetails.Count();
> * * * * if (pDetail5.get() != NULL) {
> * * * * * * * * shared_ptr<CQDetail> pDetail1 = m_rDetails.Register(1);
> * * * * * * * * nCnt = m_rDetails.Count();
> * * * * }
> * * * * nCnt = m_rDetails.Count();
>
> __________________________________________________ ______
>
> ...., i get the following error (name-mangling skipped): ...
>
> QElement.obj : error LNK2001: unresolved external symbol "public:
> virtual __thiscall CQSharedReg<class CQDetail>::~CQSharedReg<class
> CQDetail>(void)"
> QElement.obj : error LNK2001: unresolved external symbol "public:
> class boost::shared_ptr<class CQDetail> __thiscall CQSharedReg<class
> CQDetail>::Register(unsigned __int64)"
> QElement.obj : error LNK2001: unresolved external symbol "public:
> __thiscall CQSharedReg<class CQDetail>::CQSharedReg<class
> CQDetail>(void)"
>
> ...so if i interpret it right, the linker tries for example to find a
> function
> CQSharedReg<class CQDetail>::~CQSharedReg<class CQDetail>(void)
> but that function IS defined...
>
> Any help apreciated, TIA, -.rhavin


Are the namespaces same for both of them ?
 
Reply With Quote
 
 
 
 
.rhavin grobert
Guest
Posts: n/a
 
      06-11-2008
On 11 Jun., 15:06, suresh shenoy <(E-Mail Removed)> wrote:
> On Jun 11, 8:26 am, ".rhavin grobert" <(E-Mail Removed)> wrote:
>
>
>
> > Hi group....

>
> > i have the following class....
> > __________________________________________________ ___
> > // QSharedReg.hpp

>
> > typedef unsigned __int64 QUAD;
> > using namespace boost;

>
> > template<class T> struct _SQSRI {
> > QUAD qID;
> > shared_ptr<T> pItem;

>
> > };

>
> > template <class T> class CQSharedReg {
> > public:
> > CQSharedReg();
> > virtual ~CQSharedReg();
> > inline UINT Count() const {return m_vector.size();};
> > shared_ptr<T> const Get(QUAD qID) const;
> > shared_ptr<T> const GetByIdx(UINT nIdx) const;
> > shared_ptr<T> Register(QUAD qID);
> > bool Unregister(QUAD qID);

>
> > private:
> > std::vector<_SQSRI<T> > m_vector;};

>
> > __________________________________________________ ______

>
> > ...and the following implementation.....
> > __________________________________________________ ______
> > // QSharedReg.cpp

>
> > //-------------------------------------------------------------------------*----
> > template <class T> CQSharedReg<T>::CQSharedReg() {}

>
> > //-------------------------------------------------------------------------*----
> > template <class T> CQSharedReg<T>::~CQSharedReg() {}

>
> > //-------------------------------------------------------------------------*----
> > template <class T> shared_ptr<T> const CQSharedReg<T>::Get(QUAD qID)
> > const {
> > register UINT nCnt = Count();
> > _SQSRI<T> const* psqri;
> > while (nCnt-->0) {
> > psqri = &m_vector[nCnt];
> > if (psqri == NULL)
> > continue;
> > if (psqri->qID != qID)
> > continue;
> > return psqri->pItem;
> > }
> > shared_ptr<T> none;
> > return none;

>
> > }

>
> > //-------------------------------------------------------------------------*----
> > template <class T> shared_ptr<T> const CQSharedReg<T>::GetByIdx(UINT
> > nIdx) const {
> > if (nIdx >= m_vector.size()) {
> > shared_ptr<T> none;
> > return none;
> > }
> > return m_vector[nIdx].pItem;

>
> > }

>
> > //-------------------------------------------------------------------------*----
> > template <class T> shared_ptr<T> CQSharedReg<T>::Register(QUAD qID) {
> > shared_ptr<T> pItem = (shared_ptr<T>) Get(qID);
> > if (pItem.get() != NULL)
> > return pItem;
> > _SQSRI<T> sqri;
> > sqri.pItem = new T;
> > sqri.qID = qID;
> > m_vector.push_back(sqri);
> > return sqri.pItem;

>
> > }

>
> > //-------------------------------------------------------------------------*----
> > template <class T> bool CQSharedReg<T>::Unregister(QUAD qID) {
> > register UINT nCnt = Count();
> > _SQSRI<T>* psqri;
> > while (nCnt-->0) {
> > psqri = &m_vector[nCnt];
> > if (psqri == NULL)
> > continue;
> > if (psqri->qID != qID)
> > continue;
> > m_vector.erase(psqri);
> > return true;
> > }
> > return false;}

>
> > __________________________________________________ ______

>
> > the object "QSharedReg.obj" compiles fine (is there anything to
> > compile!?) but when i instatiate it in another class (here in class
> > CQElement using) ....

>
> > __________________________________________________ ______
> > // from QElement.hpp
> > CQSharedReg<CQDetail> m_rDetails;

>
> > // from QElement.cpp

>
> > UINT nCnt = m_rDetails.Count();
> > shared_ptr<CQDetail> pDetail3 = m_rDetails.Register(3);
> > nCnt = m_rDetails.Count();
> > shared_ptr<CQDetail> pDetail5 = m_rDetails.Register(5);
> > nCnt = m_rDetails.Count();
> > if (pDetail5.get() != NULL) {
> > shared_ptr<CQDetail> pDetail1 = m_rDetails.Register(1);
> > nCnt = m_rDetails.Count();
> > }
> > nCnt = m_rDetails.Count();

>
> > __________________________________________________ ______

>
> > ...., i get the following error (name-mangling skipped): ...

>
> > QElement.obj : error LNK2001: unresolved external symbol "public:
> > virtual __thiscall CQSharedReg<class CQDetail>::~CQSharedReg<class
> > CQDetail>(void)"
> > QElement.obj : error LNK2001: unresolved external symbol "public:
> > class boost::shared_ptr<class CQDetail> __thiscall CQSharedReg<class
> > CQDetail>::Register(unsigned __int64)"
> > QElement.obj : error LNK2001: unresolved external symbol "public:
> > __thiscall CQSharedReg<class CQDetail>::CQSharedReg<class
> > CQDetail>(void)"

>
> > ...so if i interpret it right, the linker tries for example to find a
> > function
> > CQSharedReg<class CQDetail>::~CQSharedReg<class CQDetail>(void)
> > but that function IS defined...

>
> > Any help apreciated, TIA, -.rhavin

>
> Are the namespaces same for both of them ?


yes...
 
Reply With Quote
 
Kai-Uwe Bux
Guest
Posts: n/a
 
      06-11-2008
..rhavin grobert wrote:

> Hi group....
>
>
>
> i have the following class....
> __________________________________________________ ___
> // QSharedReg.hpp
>
> typedef unsigned __int64 QUAD;
> using namespace boost;
>
> template<class T> struct _SQSRI {
> QUAD qID;
> shared_ptr<T> pItem;
> };
>
>
> template <class T> class CQSharedReg {
> public:
> CQSharedReg();
> virtual ~CQSharedReg();
> inline UINT Count() const {return m_vector.size();};
> shared_ptr<T> const Get(QUAD qID) const;
> shared_ptr<T> const GetByIdx(UINT nIdx) const;
> shared_ptr<T> Register(QUAD qID);
> bool Unregister(QUAD qID);
>
> private:
> std::vector<_SQSRI<T> > m_vector;
> };
> __________________________________________________ ______
>
> ...and the following implementation.....
> __________________________________________________ ______
> // QSharedReg.cpp
>

[snip]
>
> ...., i get the following error (name-mangling skipped): ...
>
> QElement.obj : error LNK2001: unresolved external symbol "public:
> virtual __thiscall CQSharedReg<class CQDetail>::~CQSharedReg<class
> CQDetail>(void)"
> QElement.obj : error LNK2001: unresolved external symbol "public:
> class boost::shared_ptr<class CQDetail> __thiscall CQSharedReg<class
> CQDetail>::Register(unsigned __int64)"
> QElement.obj : error LNK2001: unresolved external symbol "public:
> __thiscall CQSharedReg<class CQDetail>::CQSharedReg<class
> CQDetail>(void)"
>
> ...so if i interpret it right, the linker tries for example to find a
> function
> CQSharedReg<class CQDetail>::~CQSharedReg<class CQDetail>(void)
> but that function IS defined...
>
> Any help apreciated, TIA, -.rhavin


The short answer is: put the template definition into the header. For a
longer account, see the FAQ:

http://www.parashift.com/c++-faq-lit...html#faq-35.13



Best

Kai-Uwe Bux
 
Reply With Quote
 
Fernando Gómez
Guest
Posts: n/a
 
      06-11-2008
On Jun 11, 7:26 am, ".rhavin grobert" <(E-Mail Removed)> wrote:
> Hi group....
>
> i have the following class....
> __________________________________________________ ___
> // QSharedReg.hpp
>
> typedef unsigned __int64 QUAD;
> using namespace boost;
>
> template<class T> struct _SQSRI {
> QUAD qID;
> shared_ptr<T> pItem;
>
> };
>
> template <class T> class CQSharedReg {
> public:
> CQSharedReg();
> virtual ~CQSharedReg();
> inline UINT Count() const {return m_vector.size();};
> shared_ptr<T> const Get(QUAD qID) const;
> shared_ptr<T> const GetByIdx(UINT nIdx) const;
> shared_ptr<T> Register(QUAD qID);
> bool Unregister(QUAD qID);
>
> private:
> std::vector<_SQSRI<T> > m_vector;};
>
> __________________________________________________ ______
>
> ...and the following implementation.....
> __________________________________________________ ______
> // QSharedReg.cpp
>
> //-----------------------------------------------------------------------------
> template <class T> CQSharedReg<T>::CQSharedReg() {}
>
> //-----------------------------------------------------------------------------
> template <class T> CQSharedReg<T>::~CQSharedReg() {}
>
> //-----------------------------------------------------------------------------
> template <class T> shared_ptr<T> const CQSharedReg<T>::Get(QUAD qID)
> const {
> register UINT nCnt = Count();
> _SQSRI<T> const* psqri;
> while (nCnt-->0) {
> psqri = &m_vector[nCnt];
> if (psqri == NULL)
> continue;
> if (psqri->qID != qID)
> continue;
> return psqri->pItem;
> }
> shared_ptr<T> none;
> return none;
>
> }
>
> //-----------------------------------------------------------------------------
> template <class T> shared_ptr<T> const CQSharedReg<T>::GetByIdx(UINT
> nIdx) const {
> if (nIdx >= m_vector.size()) {
> shared_ptr<T> none;
> return none;
> }
> return m_vector[nIdx].pItem;
>
> }
>
> //-----------------------------------------------------------------------------
> template <class T> shared_ptr<T> CQSharedReg<T>::Register(QUAD qID) {
> shared_ptr<T> pItem = (shared_ptr<T>) Get(qID);
> if (pItem.get() != NULL)
> return pItem;
> _SQSRI<T> sqri;
> sqri.pItem = new T;
> sqri.qID = qID;
> m_vector.push_back(sqri);
> return sqri.pItem;
>
> }
>
> //-----------------------------------------------------------------------------
> template <class T> bool CQSharedReg<T>::Unregister(QUAD qID) {
> register UINT nCnt = Count();
> _SQSRI<T>* psqri;
> while (nCnt-->0) {
> psqri = &m_vector[nCnt];
> if (psqri == NULL)
> continue;
> if (psqri->qID != qID)
> continue;
> m_vector.erase(psqri);
> return true;
> }
> return false;}
>
> __________________________________________________ ______
>
> the object "QSharedReg.obj" compiles fine (is there anything to
> compile!?) but when i instatiate it in another class (here in class
> CQElement using) ....
>
> __________________________________________________ ______
> // from QElement.hpp
> CQSharedReg<CQDetail> m_rDetails;
>
> // from QElement.cpp
>
> UINT nCnt = m_rDetails.Count();
> shared_ptr<CQDetail> pDetail3 = m_rDetails.Register(3);
> nCnt = m_rDetails.Count();
> shared_ptr<CQDetail> pDetail5 = m_rDetails.Register(5);
> nCnt = m_rDetails.Count();
> if (pDetail5.get() != NULL) {
> shared_ptr<CQDetail> pDetail1 = m_rDetails.Register(1);
> nCnt = m_rDetails.Count();
> }
> nCnt = m_rDetails.Count();
>
> __________________________________________________ ______
>
> ...., i get the following error (name-mangling skipped): ...
>
> QElement.obj : error LNK2001: unresolved external symbol "public:
> virtual __thiscall CQSharedReg<class CQDetail>::~CQSharedReg<class
> CQDetail>(void)"
> QElement.obj : error LNK2001: unresolved external symbol "public:
> class boost::shared_ptr<class CQDetail> __thiscall CQSharedReg<class
> CQDetail>::Register(unsigned __int64)"
> QElement.obj : error LNK2001: unresolved external symbol "public:
> __thiscall CQSharedReg<class CQDetail>::CQSharedReg<class
> CQDetail>(void)"
>
> ...so if i interpret it right, the linker tries for example to find a
> function
> CQSharedReg<class CQDetail>::~CQSharedReg<class CQDetail>(void)
> but that function IS defined...
>
> Any help apreciated, TIA, -.rhavin


AFAIK, you cannot have a template declared in one file and the
implementation on anther one, unless the "export" keyword is used. But
(again AFAIK) there's only one compiler that implements
"export" (can't remember it's name).

Just a thought.
 
Reply With Quote
 
Triple-DES
Guest
Posts: n/a
 
      06-12-2008
On 12 Jun, 00:22, Fernando Gómez <(E-Mail Removed)> wrote:
> AFAIK, you cannot have a template declared in one file and the
> implementation on anther one, unless the "export" keyword is used.


You could, but you would have to include the definitions somehow. It
is pretty standard to write the definitions in a .tpp file (or
similar), and then #include this file in the header file.

Of course, from the compiler's POV it would not be much different from
a single file.

> But (again AFAIK) there's only one compiler that implements
> "export" (can't remember it's name).
>
> Just a thought.


Comeau has 'export'. I think Intel C++ has it too. (Since they're both
based on EDG's front end)

DP
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
typeof x == 'undefined' or x == undefined? -Lost Javascript 13 01-31-2007 12:04 AM
undefined vs. undefined (was: new Array() vs []) VK Javascript 45 09-12-2006 05:26 PM
undefined behavior or not undefined behavior? That is the question Mantorok Redgormor C Programming 70 02-17-2004 02:46 PM
Re: A Newbie Question about template template template tom_usenet C++ 0 07-24-2003 12:06 PM
Re: A Newbie Question about template template template Chris Theis C++ 2 07-24-2003 09:42 AM



Advertisments