template; how to dont instantiate a function if type is a pointer..?

  • Thread starter .rhavin grobert
  • Start date
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>::eek: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>::eek: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>::eek: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>::eek: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);
}
 
J

Juha Nieminen

..rhavin grobert said:
So, how
do i tell the compiler to please dont try to compile it IF we have a
CQVector of pointers?

You make a specialization of that template function for the case where
T is a pointer, and do nothing (or whatever appropriate).

The compiler will always choose the template which most closely
matches the parameter type, so if you specialize for a pointer type (any
pointer type) the compiler will use that when you use any pointer.
 
R

.rhavin grobert

You make a specialization of that template function for the case where
T is a pointer, and do nothing (or whatever appropriate).

The compiler will always choose the template which most closely
matches the parameter type, so if you specialize for a pointer type (any
pointer type) the compiler will use that when you use any pointer.

yes, _but how_ ?
in ....


____________________________________

#include "QVector.hpp"
struct test {
test(int = 0) {};
bool operator==(test const&) const {return false;};
bool operator<(test const&) const {return false;};
int ID() const {return 1;};
};
CQVector<test, int> tv1;
CQVector<test*, int> tv2;


____________________________________

when i add the following fn to the template
____________________________________

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();
}
__________________________

then the first vector uses that newly added (what is wrong, he should
use

T& CQVector<T,I>::add(T const& t)

because he has objects, and the second bector whitch has pointers
should use that newly added

T& CQVector<T,I>::add(T* const t)

but still uses the fn

T& CQVector<T,I>::add(I id)

so _how_ do i put this in correct syntax?


if CQVector<obj, x> use T& CQVector<T,I>::add(T const& t)
if CQVector<obj*, x> use T& CQVector<T,I>::add(T* const t)
just use T& CQVector<T,I>::add(I id) if someone does a

myVector.add(x);

?

TIA, -.rhavin;)
 

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

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,050
Latest member
AngelS122

Latest Threads

Top