R
reb
I more or less inherited some code that makes liberal use of STL, among
other things. Up to now I've sort of considered templates a kind of
black art, but I'm coming around to see how they can be useful. I'd
really like them if I could figure out this one problem. I'm porting
this code from Mac CodeWarrior to XCode which is using GCC 4.0.
CodeWarrior apparently rolled their own version of STL, where the
vector class contents are quite different than the gnu version.
I'll make this as abbreviated as possible. We have a record (actually,
many records, but this is just an example) like:
class CHelpMe : public CRefCnt
{
// usual ctors, dtor, methods. Nothing fancy here;
};
Base class CRefCnt does what it implies:
class CRefCnt
{
public:
virtual int AddRef() { return IncrementRefCnt(); }
virtual int Release() { return DecrementRefCnt();}
virtual ~CR180XmlDbRefCnt() { assert( 0 == m_iRefCnt );}
protected:
CR180XmlDbRefCnt() : m_iRefCnt( 1) {;}
virtual int IncrementRefCnt() { return ++m_iRefCnt;}
virtual int DecrementRefCnt() { int cRefs= --m_iRefCnt; if( cRefs ==
0) delete this; return cRefs;};
private:
int m_iRefCnt;
};
We also have an auto ptr class (condensed somewhat for posting):
template <class T>
class CAutoPtr
{
public:
CAutoPtr() : p( NULL) {;};
CAutoPtr(T* lp, bool bIsStrongRef= false) { if ((((p = lp) != NULL))
&& ! bIsStrongRef) p->AddRef();}
CAutoPtr(const CAutoPtr<T>& lp) { if ((p = lp.p) != NULL) p->AddRef();
}
~CAutoPtr() { if (p) p->Release(); p= NULL;}
void Release() { if( NULL == p) return; p->Release();p = NULL; }
_NoAddRefReleaseOnCAutoPtr<T>* operator->() const { return
(_NoAddRefReleaseOnCAutoPtr<T>*)p;}
operator T*() const { return p; }
T& operator*() const { assert( NULL != p ); return *p;}
T** operator&() { assert (NULL == p); return &p;}
T* operator=(T* lp) { if( p == lp) return p; if( p) p->Release(); p=
lp; if(p) p->AddRef(); return p;}
const CAutoPtr<T>& operator=(const CAutoPtr<T>& rhs) { if( p == rhs.p)
return *this; if( p) p->Release(); p= rhs.p; if( p) p->AddRef(); return
*this;}
bool operator==(T* pT) const { return p == pT;}
void Attach(T* p2) { if (p) p->Release(); p = p2; }
T* Detach() { T* pt = p; p = NULL;return pt;}
T* p;
};
Finally, we have a couple of typedefs:
typedef CAutoPtr<CHelpMe> CHelpMePtr;
typedef std::vector<CHelpMePtr> CHelpMePtrVector;
The problem comes when compiling when we get this error on the vector
typedef line:
/Developer/SDKs/MacOSX10.4u.sdk/usr/include/c++/4.0.0/bits/stl_construct.h:174:
error: no matching function for call to
'std::allocator<CHelpMePtr>::destroy(CHelpMe**)'
/Developer/SDKs/MacOSX10.4u.sdk/usr/include/c++/4.0.0/ext/new_allocator.h:107:
note: candidates are: void __gnu_cxx::new_allocator<_Tp>::destroy(_Tp*)
[with _Tp = CHelpMePtr]
My limited knowledge of STL sees this as the compiler thinking that
CAutoPtr of CHelpMe is too ambiguous for the standard allocator class.
I've tried any number of ways to resolve this, without complete
success. Note that this same code compiles and runs fine under VC++
6.0.
Any ideas? Thanks!
other things. Up to now I've sort of considered templates a kind of
black art, but I'm coming around to see how they can be useful. I'd
really like them if I could figure out this one problem. I'm porting
this code from Mac CodeWarrior to XCode which is using GCC 4.0.
CodeWarrior apparently rolled their own version of STL, where the
vector class contents are quite different than the gnu version.
I'll make this as abbreviated as possible. We have a record (actually,
many records, but this is just an example) like:
class CHelpMe : public CRefCnt
{
// usual ctors, dtor, methods. Nothing fancy here;
};
Base class CRefCnt does what it implies:
class CRefCnt
{
public:
virtual int AddRef() { return IncrementRefCnt(); }
virtual int Release() { return DecrementRefCnt();}
virtual ~CR180XmlDbRefCnt() { assert( 0 == m_iRefCnt );}
protected:
CR180XmlDbRefCnt() : m_iRefCnt( 1) {;}
virtual int IncrementRefCnt() { return ++m_iRefCnt;}
virtual int DecrementRefCnt() { int cRefs= --m_iRefCnt; if( cRefs ==
0) delete this; return cRefs;};
private:
int m_iRefCnt;
};
We also have an auto ptr class (condensed somewhat for posting):
template <class T>
class CAutoPtr
{
public:
CAutoPtr() : p( NULL) {;};
CAutoPtr(T* lp, bool bIsStrongRef= false) { if ((((p = lp) != NULL))
&& ! bIsStrongRef) p->AddRef();}
CAutoPtr(const CAutoPtr<T>& lp) { if ((p = lp.p) != NULL) p->AddRef();
}
~CAutoPtr() { if (p) p->Release(); p= NULL;}
void Release() { if( NULL == p) return; p->Release();p = NULL; }
_NoAddRefReleaseOnCAutoPtr<T>* operator->() const { return
(_NoAddRefReleaseOnCAutoPtr<T>*)p;}
operator T*() const { return p; }
T& operator*() const { assert( NULL != p ); return *p;}
T** operator&() { assert (NULL == p); return &p;}
T* operator=(T* lp) { if( p == lp) return p; if( p) p->Release(); p=
lp; if(p) p->AddRef(); return p;}
const CAutoPtr<T>& operator=(const CAutoPtr<T>& rhs) { if( p == rhs.p)
return *this; if( p) p->Release(); p= rhs.p; if( p) p->AddRef(); return
*this;}
bool operator==(T* pT) const { return p == pT;}
void Attach(T* p2) { if (p) p->Release(); p = p2; }
T* Detach() { T* pt = p; p = NULL;return pt;}
T* p;
};
Finally, we have a couple of typedefs:
typedef CAutoPtr<CHelpMe> CHelpMePtr;
typedef std::vector<CHelpMePtr> CHelpMePtrVector;
The problem comes when compiling when we get this error on the vector
typedef line:
/Developer/SDKs/MacOSX10.4u.sdk/usr/include/c++/4.0.0/bits/stl_construct.h:174:
error: no matching function for call to
'std::allocator<CHelpMePtr>::destroy(CHelpMe**)'
/Developer/SDKs/MacOSX10.4u.sdk/usr/include/c++/4.0.0/ext/new_allocator.h:107:
note: candidates are: void __gnu_cxx::new_allocator<_Tp>::destroy(_Tp*)
[with _Tp = CHelpMePtr]
My limited knowledge of STL sees this as the compiler thinking that
CAutoPtr of CHelpMe is too ambiguous for the standard allocator class.
I've tried any number of ways to resolve this, without complete
success. Note that this same code compiles and runs fine under VC++
6.0.
Any ideas? Thanks!