Re: Initializing std::auto_ptr
On 2011-04-28 03:14, Matthias Hofmann wrote:
Hello everybody!
I just thought that I had understood everything about std::auto_ptr, but now
I am confused about an initialization issue. We all know that the following
code should not compile:
auto_ptr<T> ptr = new T;
Agreed.
This is because auto_ptr's constructor taking a pointer argument is declared
explicit and therefore cannot be used for implicit conversion. And even if
it were not declared explicit, the temporary created during this copy
initialization would be an rvalue and thus could not be bound to the
non-const reference accepted by auto_ptr's copy constructor.
This conclusion is wrong, see below.
I assume that
for the latter reason, the following code would be also illegal:
auto_ptr<T> ptr = auto_ptr<T>( new T );
This initialization is OK, see below.
However, according to the statements of one or more persons on the following
web site, my second example should compile:
http://stackoverflow.com/questions/270347/replacing-auto-ptr-in-vc-8
I assume that this is wrong, but I am not sure. Does the standard permit the
elision of the explicitly created temporary and treat the code as if it were
direct initialization?
This has nothing to do with elision. If elision would be the only
reason, the code should still be ill-formed, but elision is not
(or better: should not be) the reason.
Is it actually possible to classify my second example
as copy initialization at all?
This is copy-initialization, it clearly matches the form requirements as
described in 8.5 p. 14 of the FDIS document:
"The initialization that occurs in the form
T x = a;
as well as in argument passing, function return, throwing an exception
(15.1), handling an exception (15.3), and aggregate member
initialization (8.5.1) is called copy-initialization. [ Note:
Copy-initialization may invoke a move (12.8). ?end note ]"
After all, we have both, the direct
initialization with an argument of type pointer-to-T, and the copy
initialization with the temporary as the argument in the assignment to
"ptr". So is my second example legal?
It is not immediately obvious from the specification of std::auto_ptr,
but the intend is to allow for constructing from rvalues of
std::auto_ptr, which would be a "moving copy-initialization" in the
language of C++0x. Note that auto_ptr provides the following
non-explicit constructor
auto_ptr(auto_ptr_ref<X>) throw();
and the following non-explicit conversion function:
template<class Y> operator auto_ptr_ref<Y>() throw();
This works (even though this conversion function is non-const), because
of the old and special rule about member function calls (without
reference-qualifiers) from rvalues. You are right that the
copy-constructor of std::auto_ptr cannot accept an rvalue and is not
feasible in this context.
In C++0x the following non-normative wording has also be added to
std::auto_ptr to make the intention clearer:
"Instances of auto_ptr meet the requirements of MoveConstructible and
MoveAssignable, but do not meet the requirements of CopyConstructible
and CopyAssignable."
This indirectly supports the idea that move-construction via
copy-initialization of std::auto_ptr is intended to be supported,
because the MoveConstructible requirements impose that
copy-initialization is supported because of this initialization requirement:
T u = rv;
from Table 20 ? MoveConstructible requirements.
HTH & Greetings from Bremen,
Daniel Kr?gler
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]