R
.rhavin grobert
hello;-)
i have that following little template that defines some type of
vector.
it works with structs and i want to use it also for simple pointers.
the problem is, in following function...
______________________________________
template <class T, typename I>
T& CQVector<T,I>::add(I id)
{
critical_enter();
int iIndex = find_id(id);
if (iIndex < 0)
{
T t(id); // **** <-- here ****
m_vec.push_back(t);
iIndex = m_vec.size() - 1;
}
critical_leave();
return m_vec[iIndex];
}
______________________________________
....the line T t(id); doenst work, what simply doesnt matter, because
that whole function is never needed if i have CQVector<some*>. So, how
do i tell the compiler to please dont try to compile it IF we have a
CQVector of pointers?
here is the whole template...
______________________________________
//
****************************************************************************
// * template class CQVector
declaration *
//
****************************************************************************
template <
class T, // class of comparable (op<, op==) elements to host
in QVector
typename I=int // type of ID, must be accessible by elements public
ID()-func
class CQVector
{
public:
//
------------------------------------------------------------------------
// construction and destruction
// default constructor
CQVector();
// default destructor
virtual ~CQVector();
//
------------------------------------------------------------------------
// special vector functions
// start critical access
inline void critical_enter() const
{EnterCriticalSection(&m_Crit);};
// end critical access
inline void critical_leave() const
{LeaveCriticalSection(&m_Crit);};
// set invalid element
virtual inline void invalid(T const& invalid) {m_invalid =
invalid;};
//
------------------------------------------------------------------------
// vector informative functions
// size of vector
inline UINT size() const {return
m_vec.size();};
// constant ref to inalid element
inline T const& invalid() const {return
m_invalid;};
// ref to invalid element thru null-element
inline T& null() {m_null = m_inv; return
m_null;};
// find an element, returns index or -1 if none is found
virtual int find(T const& t) const;
// find an element by its ID, returns index or -1 if none is found
virtual int find_id(I const& i) const;
//
------------------------------------------------------------------------
// single element access (external critical sync needed!)
// get const ref
T const& operator[] (UINT nIndex) const;
// get ref
T& operator[] (UINT nIndex);
// get const ref to element of given ID
T const& operator() (I const& i) const;
// get const ref to element of given ID
T& operator() (I const& i);
//
------------------------------------------------------------------------
// removal of elements
// remove element of given index from vector
virtual bool remove(UINT nIndex);
// clear registry, remove all elements
virtual void clear();
// remove element of given ID from vector
bool remove_id(I id);
// remove an element from the vector
bool remove_obj(T const& t);
//
------------------------------------------------------------------------
// insert and adding of elements
// add an element to the vector
virtual T& add(T const& t);
// add an element to the vector
virtual T& add(I id);
private:
std::vector<T> m_vec;
T m_invalid;
T m_null;
mutable CRITICAL_SECTION m_Crit;
mutable I m_idLast;
mutable bool m_fLastValid;
mutable UINT m_nLastIdx;
I _ID(T* const& pt) const {return pt->ID();};
I _ID(T const& t) const {return t.ID();};
};
//
****************************************************************************
// * template class CQVector
definition *
//
****************************************************************************
//-----------------------------------------------------------------------------
// default constructor
template <class T, typename I>
CQVector<T,I>::CQVector()
{
m_fLastValid = false;
InitializeCriticalSection(&m_Crit);
}
//-----------------------------------------------------------------------------
// default destructor
template <class T, typename I>
CQVector<T,I>::~CQVector()
{
clear();
DeleteCriticalSection(&m_Crit);
}
//-----------------------------------------------------------------------------
// clear registry
template <class T, typename I>
void CQVector<T,I>::clear()
{
critical_enter();
m_vec.clear();
m_fLastValid = false;
critical_leave();
}
//-----------------------------------------------------------------------------
// get const ref to item (sync_extern!)
template <class T, typename I>
T const& CQVector<T,I>:perator[](UINT nIndex) const
{
if (nIndex < m_vec.size())
return m_vec[nIndex];
return m_invalid;
}
//-----------------------------------------------------------------------------
// get ref to item (sync extern!)
template <class T, typename I>
T& CQVector<T,I>:perator[](UINT nIndex)
{
if (nIndex < m_vec.size())
return m_vec[nIndex];
m_null = m_invalid;
return m_null;
}
//-----------------------------------------------------------------------------
// add an element to the vector
template <class T, typename I>
T& CQVector<T,I>::add(T const& t)
{
critical_enter();
m_vec.push_back(t);
critical_leave();
return m_vec.back();
}
//-----------------------------------------------------------------------------
// add an element to the vector
template <class T, typename I>
T& CQVector<T,I>::add(I id)
{
critical_enter();
int iIndex = find_id(id);
if (iIndex < 0)
{
T t(id);
m_vec.push_back(t);
iIndex = m_vec.size() - 1;
}
critical_leave();
return m_vec[iIndex];
}
//-----------------------------------------------------------------------------
// remove element of given index from vector
template <class T, typename I>
bool CQVector<T,I>::remove(UINT nIndex)
{
critical_enter();
if (nIndex >= m_vec.size())
{
critical_leave();
return false;
}
m_vec.erase(m_vec.begin() + nIndex);
if (m_fLastValid)
{
if (m_nLastIdx == nIndex)
m_fLastValid = false;
if (m_nLastIdx > nIndex)
m_nLastIdx--;
}
critical_leave();
return true;
}
//-----------------------------------------------------------------------------
// find an element, returns index or -1 if none is found
template <class T, typename I>
int CQVector<T,I>::find(T const& t) const
{
critical_enter();
int iCnt = m_vec.size();
while (iCnt-->0)
{
if (m_vec[iCnt] == t)
break;
}
critical_leave();
return iCnt;
}
//-----------------------------------------------------------------------------
// find an element, returns index or -1 if none is found
template <class T, typename I>
int CQVector<T,I>::find_id(I const& i) const
{
critical_enter();
if (m_fLastValid)
{
if (m_idLast == i)
{
return m_nLastIdx;
critical_leave();
}
}
int iCnt = m_vec.size();
while (iCnt-->0)
{
if (_ID(m_vec[iCnt]) == i)
{
m_fLastValid = true;
m_nLastIdx = iCnt;
break;
}
}
critical_leave();
return iCnt;
}
//-----------------------------------------------------------------------------
// get const ref to element of given ID
template <class T, typename I>
T const& CQVector<T,I>:perator() (I const& i) const
{
int i = find_id(i);
if (i < 0)
return m_invalid;
return m_vec;
}
//-----------------------------------------------------------------------------
// get const ref to element of given ID
template <class T, typename I>
T& CQVector<T,I>:perator() (I const& i)
{
int idx = find_id(i);
if (idx < 0)
{
m_null = m_invalid;
return m_null;
}
return m_vec[idx];
}
//-----------------------------------------------------------------------------
// remove element of given ID from vector
template <class T, typename I>
bool CQVector<T,I>::remove_id(I id)
{
critical_enter();
int i = find_id(i);
if (i >= 0)
remove(i);
critical_leave();
return (i>=0);
}
//-----------------------------------------------------------------------------
// remove an element to the vector
template <class T, typename I>
bool CQVector<T,I>::remove_obj(T const& t)
{
critical_enter();
int i = find(t);
if (i >= 0)
remove(i);
critical_leave();
return (i>=0);
}
i have that following little template that defines some type of
vector.
it works with structs and i want to use it also for simple pointers.
the problem is, in following function...
______________________________________
template <class T, typename I>
T& CQVector<T,I>::add(I id)
{
critical_enter();
int iIndex = find_id(id);
if (iIndex < 0)
{
T t(id); // **** <-- here ****
m_vec.push_back(t);
iIndex = m_vec.size() - 1;
}
critical_leave();
return m_vec[iIndex];
}
______________________________________
....the line T t(id); doenst work, what simply doesnt matter, because
that whole function is never needed if i have CQVector<some*>. So, how
do i tell the compiler to please dont try to compile it IF we have a
CQVector of pointers?
here is the whole template...
______________________________________
//
****************************************************************************
// * template class CQVector
declaration *
//
****************************************************************************
template <
class T, // class of comparable (op<, op==) elements to host
in QVector
typename I=int // type of ID, must be accessible by elements public
ID()-func
class CQVector
{
public:
//
------------------------------------------------------------------------
// construction and destruction
// default constructor
CQVector();
// default destructor
virtual ~CQVector();
//
------------------------------------------------------------------------
// special vector functions
// start critical access
inline void critical_enter() const
{EnterCriticalSection(&m_Crit);};
// end critical access
inline void critical_leave() const
{LeaveCriticalSection(&m_Crit);};
// set invalid element
virtual inline void invalid(T const& invalid) {m_invalid =
invalid;};
//
------------------------------------------------------------------------
// vector informative functions
// size of vector
inline UINT size() const {return
m_vec.size();};
// constant ref to inalid element
inline T const& invalid() const {return
m_invalid;};
// ref to invalid element thru null-element
inline T& null() {m_null = m_inv; return
m_null;};
// find an element, returns index or -1 if none is found
virtual int find(T const& t) const;
// find an element by its ID, returns index or -1 if none is found
virtual int find_id(I const& i) const;
//
------------------------------------------------------------------------
// single element access (external critical sync needed!)
// get const ref
T const& operator[] (UINT nIndex) const;
// get ref
T& operator[] (UINT nIndex);
// get const ref to element of given ID
T const& operator() (I const& i) const;
// get const ref to element of given ID
T& operator() (I const& i);
//
------------------------------------------------------------------------
// removal of elements
// remove element of given index from vector
virtual bool remove(UINT nIndex);
// clear registry, remove all elements
virtual void clear();
// remove element of given ID from vector
bool remove_id(I id);
// remove an element from the vector
bool remove_obj(T const& t);
//
------------------------------------------------------------------------
// insert and adding of elements
// add an element to the vector
virtual T& add(T const& t);
// add an element to the vector
virtual T& add(I id);
private:
std::vector<T> m_vec;
T m_invalid;
T m_null;
mutable CRITICAL_SECTION m_Crit;
mutable I m_idLast;
mutable bool m_fLastValid;
mutable UINT m_nLastIdx;
I _ID(T* const& pt) const {return pt->ID();};
I _ID(T const& t) const {return t.ID();};
};
//
****************************************************************************
// * template class CQVector
definition *
//
****************************************************************************
//-----------------------------------------------------------------------------
// default constructor
template <class T, typename I>
CQVector<T,I>::CQVector()
{
m_fLastValid = false;
InitializeCriticalSection(&m_Crit);
}
//-----------------------------------------------------------------------------
// default destructor
template <class T, typename I>
CQVector<T,I>::~CQVector()
{
clear();
DeleteCriticalSection(&m_Crit);
}
//-----------------------------------------------------------------------------
// clear registry
template <class T, typename I>
void CQVector<T,I>::clear()
{
critical_enter();
m_vec.clear();
m_fLastValid = false;
critical_leave();
}
//-----------------------------------------------------------------------------
// get const ref to item (sync_extern!)
template <class T, typename I>
T const& CQVector<T,I>:perator[](UINT nIndex) const
{
if (nIndex < m_vec.size())
return m_vec[nIndex];
return m_invalid;
}
//-----------------------------------------------------------------------------
// get ref to item (sync extern!)
template <class T, typename I>
T& CQVector<T,I>:perator[](UINT nIndex)
{
if (nIndex < m_vec.size())
return m_vec[nIndex];
m_null = m_invalid;
return m_null;
}
//-----------------------------------------------------------------------------
// add an element to the vector
template <class T, typename I>
T& CQVector<T,I>::add(T const& t)
{
critical_enter();
m_vec.push_back(t);
critical_leave();
return m_vec.back();
}
//-----------------------------------------------------------------------------
// add an element to the vector
template <class T, typename I>
T& CQVector<T,I>::add(I id)
{
critical_enter();
int iIndex = find_id(id);
if (iIndex < 0)
{
T t(id);
m_vec.push_back(t);
iIndex = m_vec.size() - 1;
}
critical_leave();
return m_vec[iIndex];
}
//-----------------------------------------------------------------------------
// remove element of given index from vector
template <class T, typename I>
bool CQVector<T,I>::remove(UINT nIndex)
{
critical_enter();
if (nIndex >= m_vec.size())
{
critical_leave();
return false;
}
m_vec.erase(m_vec.begin() + nIndex);
if (m_fLastValid)
{
if (m_nLastIdx == nIndex)
m_fLastValid = false;
if (m_nLastIdx > nIndex)
m_nLastIdx--;
}
critical_leave();
return true;
}
//-----------------------------------------------------------------------------
// find an element, returns index or -1 if none is found
template <class T, typename I>
int CQVector<T,I>::find(T const& t) const
{
critical_enter();
int iCnt = m_vec.size();
while (iCnt-->0)
{
if (m_vec[iCnt] == t)
break;
}
critical_leave();
return iCnt;
}
//-----------------------------------------------------------------------------
// find an element, returns index or -1 if none is found
template <class T, typename I>
int CQVector<T,I>::find_id(I const& i) const
{
critical_enter();
if (m_fLastValid)
{
if (m_idLast == i)
{
return m_nLastIdx;
critical_leave();
}
}
int iCnt = m_vec.size();
while (iCnt-->0)
{
if (_ID(m_vec[iCnt]) == i)
{
m_fLastValid = true;
m_nLastIdx = iCnt;
break;
}
}
critical_leave();
return iCnt;
}
//-----------------------------------------------------------------------------
// get const ref to element of given ID
template <class T, typename I>
T const& CQVector<T,I>:perator() (I const& i) const
{
int i = find_id(i);
if (i < 0)
return m_invalid;
return m_vec;
}
//-----------------------------------------------------------------------------
// get const ref to element of given ID
template <class T, typename I>
T& CQVector<T,I>:perator() (I const& i)
{
int idx = find_id(i);
if (idx < 0)
{
m_null = m_invalid;
return m_null;
}
return m_vec[idx];
}
//-----------------------------------------------------------------------------
// remove element of given ID from vector
template <class T, typename I>
bool CQVector<T,I>::remove_id(I id)
{
critical_enter();
int i = find_id(i);
if (i >= 0)
remove(i);
critical_leave();
return (i>=0);
}
//-----------------------------------------------------------------------------
// remove an element to the vector
template <class T, typename I>
bool CQVector<T,I>::remove_obj(T const& t)
{
critical_enter();
int i = find(t);
if (i >= 0)
remove(i);
critical_leave();
return (i>=0);
}