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.
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 other active issues in [util.smartptr.shared.const].
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>explicitshared_ptr(auto_ptr<Y> &&r); template <class Y, class D>explicitshared_ptr(unique_ptr<Y, D> &&r);