PHWinfo banniere

Titres
PORTAIL ANNUAIRE ARTICLES COMPARATEUR HÉBERGEURS DEVIS FORUMS RÉDUCTEUR D'URL
Précédent   PHWinfo > Autres forums > Forum Programmation & Conception > comp.lang.cplus > template; how to dont instantiate a function if type is a pointer..?
S'inscrire FAQ Membres Recherche Messages du jour Marquer les forums comme lus
template; how to dont instantiate a function if type is a pointer..?

Réponse
 
LinkBack Outils de la discussion
Vieux 02/07/2008, 16h26   #1
.rhavin grobert
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut 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
>


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[i];
}

//-----------------------------------------------------------------------------
// 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);
}
  Réponse avec citation
Vieux 02/07/2008, 17h30   #2
Juha Nieminen
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: template; how to dont instantiate a function if type is a pointer..?

..rhavin grobert wrote:
> 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éponse avec citation
Vieux 02/07/2008, 17h58   #3
.rhavin grobert
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: template; how to dont instantiate a function if type is apointer..?

On 2 Jul., 18:30, Juha Nieminen <nos...@thanks.invalid> wrote:
> .rhavin grobert wrote:
> > 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, 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
  Réponse avec citation
Réponse


Outils de la discussion

Règles de messages
Vous ne pouvez pas créer de nouvelles discussions
Vous ne pouvez pas envoyer des réponses
Vous ne pouvez pas envoyer des pièces jointes
Vous ne pouvez pas modifier vos messages

Les balises BB sont activées : oui
Les smileys sont activés : oui
La balise [IMG] est activée : oui
Le code HTML peut être employé : non
Trackbacks are oui
Pingbacks are oui
Refbacks are oui


Fuseau horaire GMT +1. Il est actuellement 19h15.


Édité par : vBulletin® version 3.7.3
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.2.0 RC5 Tous droits réservés.
Version française #16 par l'association vBulletin francophone
PHWinfo est un site Éducation Sans Frontières ©2000-2008
Ad Management by RedTyger
©Tous droits réservés par les parties respectives
Page generated in 0,14093 seconds with 11 queries