intrusive_ptr and overloading not working under VC++ 8

I ran onto a problem when using intrusive_ptr, overloading and MS visual studio 8 All my classes derive a reference counted class RefCnt. For example: class GLTexture : public RefCnt {...}; class GLRenderBuffer : public RefCnt {...}; I define smart pointers using the intrusive_ptr class: typedef boost::intrusive_ptr<GLTexture> GLTexturePtr; typedef boost::intrusive_ptr<GLRenderBuffer> GLRenderBufferPtr; Than I define a function accepting both GLTexturePtr and GLRenderBufferPtr : void attachTarget(GLTexturePtr aTexture); void attachTarget(GLRenderBufferPtr aBuffer); invoking <code>attach(new GLTexture)</code> leads to an error: ambiguous function call. The reason is in the contructor of intrusive_ptr: template<class U> intrusive_ptr(intrusive_ptr<U> const & rhs) ... which allows an invocation with an unrelated pointer. Changing the constructor to template<class U> intrusive_ptr( intrusive_ptr<U> const & rhs, typename enable_if<boost::is_convertible<typename boost::add_const<U*>::type, typename boost::add_const<T*>::type >
::type* dummy = NULL )
resolves the problem. I think this is a bug. Best, Stefan

Stefan Popov wrote:
I ran onto a problem when using intrusive_ptr, overloading and MS visual studio 8
All my classes derive a reference counted class RefCnt. For example:
class GLTexture : public RefCnt {...}; class GLRenderBuffer : public RefCnt {...};
I define smart pointers using the intrusive_ptr class:
typedef boost::intrusive_ptr<GLTexture> GLTexturePtr; typedef boost::intrusive_ptr<GLRenderBuffer> GLRenderBufferPtr;
Than I define a function accepting both GLTexturePtr and GLRenderBufferPtr :
void attachTarget(GLTexturePtr aTexture); void attachTarget(GLRenderBufferPtr aBuffer);
invoking <code>attach(new GLTexture)</code> leads to an error: ambiguous function call.
The reason is in the contructor of intrusive_ptr: template<class U> intrusive_ptr(intrusive_ptr<U> const & rhs) ... which allows an invocation with an unrelated pointer.
This program: #include <boost/intrusive_ptr.hpp> class RefCnt { }; void intrusive_ptr_add_ref( RefCnt * ); void intrusive_ptr_release( RefCnt * ); class GLTexture: public RefCnt { }; class GLRenderBuffer: public RefCnt { }; typedef boost::intrusive_ptr<GLTexture> GLTexturePtr; typedef boost::intrusive_ptr<GLRenderBuffer> GLRenderBufferPtr; void attachTarget(GLTexturePtr aTexture); void attachTarget(GLRenderBufferPtr aBuffer); int main() { attachTarget( new GLTexture ); } compiles for me under MSVC 8.

Sorry, I posted the wrong code. Here is the code causing the ambiguouty: class RefCnt {}; inline void intrusive_ptr_add_ref(RefCnt *aObj); inline void intrusive_ptr_release(RefCnt *aObj); class GLTexture: public RefCnt {}; class GLOffscreenTexture: public GLTexture {}; class GLRenderBuffer: public RefCnt {}; typedef intrusive_ptr<GLTexture> GLTexturePtr; typedef intrusive_ptr<GLOffscreenTexture> GLOffscreenTexturePtr; typedef intrusive_ptr<GLRenderBuffer> GLRenderBufferPtr; void attachTarget(GLTexturePtr aTexture); void attachTarget(GLRenderBufferPtr aBuffer); int main() { GLOffscreenTexturePtr ptr = new GLOffscreenTexture; attachTarget(ptr); } Produces: ...\tst.cpp(...) : error C2668: 'attachTarget' : ambiguous call to overloaded function Peter Dimov wrote:
Stefan Popov wrote:
I ran onto a problem when using intrusive_ptr, overloading and MS visual studio 8
All my classes derive a reference counted class RefCnt. For example:
class GLTexture : public RefCnt {...}; class GLRenderBuffer : public RefCnt {...};
I define smart pointers using the intrusive_ptr class:
typedef boost::intrusive_ptr<GLTexture> GLTexturePtr; typedef boost::intrusive_ptr<GLRenderBuffer> GLRenderBufferPtr;
Than I define a function accepting both GLTexturePtr and GLRenderBufferPtr :
void attachTarget(GLTexturePtr aTexture); void attachTarget(GLRenderBufferPtr aBuffer);
invoking <code>attach(new GLTexture)</code> leads to an error: ambiguous function call.
The reason is in the contructor of intrusive_ptr: template<class U> intrusive_ptr(intrusive_ptr<U> const & rhs) ... which allows an invocation with an unrelated pointer.
This program:
#include <boost/intrusive_ptr.hpp>
class RefCnt { };
void intrusive_ptr_add_ref( RefCnt * ); void intrusive_ptr_release( RefCnt * );
class GLTexture: public RefCnt { };
class GLRenderBuffer: public RefCnt { };
typedef boost::intrusive_ptr<GLTexture> GLTexturePtr; typedef boost::intrusive_ptr<GLRenderBuffer> GLRenderBufferPtr;
void attachTarget(GLTexturePtr aTexture); void attachTarget(GLRenderBufferPtr aBuffer);
int main() { attachTarget( new GLTexture ); }
compiles for me under MSVC 8.
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

I agree, the shared_ptr also lacks for that functionality. -----Original Message----- From: boost-bounces@lists.boost.org [mailto:boost-bounces@lists.boost.org] On Behalf Of Stefan Popov Sent: Friday, December 09, 2005 9:09 PM To: boost@lists.boost.org Subject: [boost] intrusive_ptr and overloading not working under VC++ 8 I ran onto a problem when using intrusive_ptr, overloading and MS visual studio 8 All my classes derive a reference counted class RefCnt. For example: class GLTexture : public RefCnt {...}; class GLRenderBuffer : public RefCnt {...}; I define smart pointers using the intrusive_ptr class: typedef boost::intrusive_ptr<GLTexture> GLTexturePtr; typedef boost::intrusive_ptr<GLRenderBuffer> GLRenderBufferPtr; Than I define a function accepting both GLTexturePtr and GLRenderBufferPtr : void attachTarget(GLTexturePtr aTexture); void attachTarget(GLRenderBufferPtr aBuffer); invoking <code>attach(new GLTexture)</code> leads to an error: ambiguous function call. The reason is in the contructor of intrusive_ptr: template<class U> intrusive_ptr(intrusive_ptr<U> const & rhs) ... which allows an invocation with an unrelated pointer. Changing the constructor to template<class U> intrusive_ptr( intrusive_ptr<U> const & rhs, typename enable_if<boost::is_convertible<typename boost::add_const<U*>::type, typename boost::add_const<T*>::type >
::type* dummy = NULL )
resolves the problem. I think this is a bug. Best, Stefan _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
participants (3)
-
art
-
Peter Dimov
-
Stefan Popov