This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of CD1 status.

### 541. shared_ptr template assignment and void

Section: 20.3.2.2 [util.smartptr.shared], 99 [tr.util.smartptr.shared] Status: CD1 Submitter: Martin Sebor Opened: 2005-10-16 Last modified: 2016-01-28

Priority: Not Prioritized

View all other issues in [util.smartptr.shared].

View all issues with CD1 status.

Discussion:

Is the void specialization of the template assignment operator taking a shared_ptr<void> as an argument supposed be well-formed?

I.e., is this snippet well-formed:

>     shared_ptr<void> p;
>     p.operator=<void>(p);

Gcc complains about auto_ptr<void>::operator*() returning a reference to void. I suspect it's because shared_ptr has two template assignment operators, one of which takes auto_ptr, and the auto_ptr template gets implicitly instantiated in the process of overload resolution.

The only way I see around it is to do the same trick with auto_ptr<void> operator*() as with the same operator in shared_ptr<void>.

PS Strangely enough, the EDG front end doesn't mind the code, even though in a small test case (below) I can reproduce the error with it as well.

>     template <class T>
>     struct A { T& operator*() { return *(T*)0; } };

>     template <class T>
>     struct B {
>         void operator= (const B&) { }
>         template <class U>
>         void operator= (const B<U>&) { }
>         template <class U>
>         void operator= (const A<U>&) { }
>     };

>     int main ()
>     {
>         B<void> b;
>         b.operator=<void>(b);
>     }

Proposed resolution:

In [lib.memory] change:

>     template<class X> class auto_ptr;
>     template<> class auto_ptr<void>;

In [lib.auto.ptr]/2 add the following before the last closing brace:

>     template<> class auto_ptr<void>
>     {
>     public:
>         typedef void element_type;
>     };