undefined external template fn?

R

.rhavin grobert

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;)
 
S

suresh shenoy

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 ?
 
R

.rhavin grobert

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...
 
K

Kai-Uwe Bux

..rhavin grobert said:
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-lite/templates.html#faq-35.13



Best

Kai-Uwe Bux
 
F

Fernando Gómez

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.
 
T

Triple-DES

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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,042
Latest member
icassiem

Latest Threads

Top