Connecting Tech Pros Worldwide Help | Site Map

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

 
LinkBack Thread Tools Search this Thread
  #1  
Old July 2nd, 2008, 03:38 PM
.rhavin grobert
Guest
 
Posts: n/a
Default template; how to dont instantiate a function if type is a pointer..?

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
Quote:
>
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>::operator[](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>::operator[](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>::operator() (I const& i) const
{
int i = find_id(i);
if (i < 0)
return m_invalid;
return m_vec[i];
}

//-----------------------------------------------------------------------------
// get const ref to element of given ID
template <class T, typename I>
T& CQVector<T,I>::operator() (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);
}

  #2  
Old July 2nd, 2008, 04:35 PM
Juha Nieminen
Guest
 
Posts: n/a
Default Re: template; how to dont instantiate a function if type is a pointer..?

..rhavin grobert wrote:
Quote:
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.
  #3  
Old July 2nd, 2008, 05:05 PM
.rhavin grobert
Guest
 
Posts: n/a
Default Re: template; how to dont instantiate a function if type is apointer..?

On 2 Jul., 18:30, Juha Nieminen <nos...@thanks.invalidwrote:
Quote:
.rhavin grobert wrote:
Quote:
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.
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, inttv1;
CQVector<test*, inttv2;


____________________________________

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, xuse T& CQVector<T,I>::add(T const& t)
if CQVector<obj*, xuse 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;)
 

Bookmarks

Thread Tools Search this Thread
Search this Thread:

Advanced Search

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 Off
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On

Popular Articles

What is Bytes?

We are a network of experts and professionals in IT and software development that help one another with answers to tough questions and share insights. Get the best answers to your questions from over 220,840 network members.