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

### 925. `shared_ptr`'s explicit conversion from `unique_ptr`

Section: 20.3.2.2.2 [util.smartptr.shared.const] Status: C++11 Submitter: Rodolfo Lima Opened: 2008-10-12 Last modified: 2016-01-28

Priority: Not Prioritized

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

View all issues with C++11 status.

Discussion:

The current working draft (N2798), section 20.3.2.2.2 [util.smartptr.shared.const] declares `shared_ptr`'s constructor that takes a rvalue reference to `unique_ptr` and `auto_ptr` as being explicit, affecting several valid smart pointer use cases that would take advantage of this conversion being implicit, for example:

>     class A;
>     std::unique_ptr<A> create();
>     void process(std::shared_ptr<A> obj);

>     int main()
>     {
>        process(create());                  // use case #1
>        std::unique_ptr<A> uobj = create();
>        process(std::move(uobj));           // use case #2
>        return 0;
>     }

If `unique_ptr` to `shared_ptr` conversions are explicit, the above lines should be written:

>     process(std::shared_ptr<A>(create()));        // use case #1
>     process(std::shared_ptr<A>(std::move(uobj))); // use case #2

The extra cast required doesn't seems to give any benefits to the user, nor protects him of any unintended conversions, this being the raison d'etre of explicit constructors.

It seems that this constructor was made explicit to mimic the conversion from `auto_ptr` in pre-rvalue reference days, which accepts both lvalue and rvalue references. Although this decision was valid back then, C++0x allows the user to express in a clear and non verbose manner when he wants move semantics to be employed, be it implicitly (use case 1) or explicitly (use case 2).

[ Batavia (2009-05): ]

> Howard and Alisdair like the motivating use cases and the proposed resolution.

> Move to Tentatively Ready.

Proposed resolution:

In both 20.3.2.2 [util.smartptr.shared] paragraph 1 and 20.3.2.2.2 [util.smartptr.shared.const] change:

>     template <class Y> explicit shared_ptr(auto_ptr<Y> &&r);
>     template <class Y, class D> explicit shared_ptr(unique_ptr<Y, D> &&r);