Re: [boost] intrusive_ptr and overloading not working under VC++ 8

Does intrusive_ptr work with overloading on any other compiler? This is a general problem and as I proposed above to solve the ambiguity you have to use SFINE in template constructor of intrusive_ptr/shared pointer. template< class T2 > shared_ptr( const shared_ptr<T2>& s_ptr, typename enable_if<is_convertible<T*,T2*>::result, void* >::type = 0) { ... } I think it should be added to boost smartptr. Artyom "Stefan Popov" <stefan.popov@gmail.com> wrote in message news:<6dbc126a0512091009y28a7c321if705f64ef22999f0@mail.gmail.com>...
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

"art" <art@deep-dream.com> writes:
Does intrusive_ptr work with overloading on any other compiler?
This is a general problem and as I proposed above to solve the ambiguity you have to use SFINE in template constructor of intrusive_ptr/shared pointer.
template< class T2 > shared_ptr( const shared_ptr<T2>& s_ptr, typename enable_if<is_convertible<T*,T2*>::result, void* >::type = 0) { ... }
I think it should be added to boost smartptr.
That isn't really a complete solution: struct Base {}; struct Derived : Base {}; struct Bottom : Derived {}; int f(shared_ptr<Base>); // #1 int f(shared_ptr<Derived>); // #2 shared_ptr<Bottom> x(new Bottom); int y = f(x); // Should call #2, but is ambiguous will still fail, and there's not really any way to make it work. -- Dave Abrahams Boost Consulting www.boost-consulting.com

On 12/10/05, David Abrahams <dave@boost-consulting.com> wrote: [snip]
That isn't really a complete solution:
struct Base {}; struct Derived : Base {}; struct Bottom : Derived {};
int f(shared_ptr<Base>); // #1 int f(shared_ptr<Derived>); // #2
shared_ptr<Bottom> x(new Bottom); int y = f(x); // Should call #2, but is ambiguous
will still fail, and there's not really any way to make it work.
But at least completely unmatchable choices wont get in the way, turning a completely legitimate call an ambigous one. As was stated in another thread: struct A {}; struct B {}; struct C : B {}; void foo(shared_ptr<A>); void foo(shared_ptr<B>); foo(new C()); doesnt work because of A, that has nothing to do with A... IMHO, being able to do this is a must.
-- Dave Abrahams Boost Consulting www.boost-consulting.com
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Felipe Magno de Almeida <felipe.m.almeida@gmail.com> writes:
On 12/10/05, David Abrahams <dave@boost-consulting.com> wrote:
[snip]
That isn't really a complete solution:
struct Base {}; struct Derived : Base {}; struct Bottom : Derived {};
int f(shared_ptr<Base>); // #1 int f(shared_ptr<Derived>); // #2
shared_ptr<Bottom> x(new Bottom); int y = f(x); // Should call #2, but is ambiguous
will still fail, and there's not really any way to make it work.
But at least completely unmatchable choices wont get in the way, turning a completely legitimate call an ambigous one.
I know. I suggested the SFINAE thing to Peter several months ago. I'm just pointing out that it has serious limitations. -- Dave Abrahams Boost Consulting www.boost-consulting.com

Felipe Magno de Almeida wrote:
struct A {}; struct B {}; struct C : B {};
void foo(shared_ptr<A>); void foo(shared_ptr<B>);
foo(new C());
doesnt work because of A, that has nothing to do with A...
IMHO, being able to do this is a must.
This is useful functionality, but the suggested "trivial implementation" breaks shared_ptr/intrusive_ptr on all legacy compilers (easy to fix) and carries the cost of including a type traits header (possible to fix if someone cares to find the time to do it). Note also that the above code is not required to work with tr1::shared_ptr (not so easy to fix :-) ).

On 12/10/05, Peter Dimov <pdimov@mmltd.net> wrote: [snip]
This is useful functionality, but the suggested "trivial implementation" breaks shared_ptr/intrusive_ptr on all legacy compilers (easy to fix) and carries the cost of including a type traits header (possible to fix if someone cares to find the time to do it).
Doenst boost have a no-sfinae-support defined when the compiler doesnt support it? That could guard the type_traits header too. Then the type_traits would be needed only if the compiler has support for SFINAE. Which is ok in this case, isnt?
Note also that the above code is not required to work with tr1::shared_ptr (not so easy to fix :-) ).
That really is something to think about... Now I'm not so sure anymore. best regards -- Felipe Magno de Almeida
participants (4)
-
art
-
David Abrahams
-
Felipe Magno de Almeida
-
Peter Dimov