Re: template copy constructor
Vladimir Grigoriev wrote:
[auto_ptr-like odd_ptr class]
However looking through some articles about auto_ptr I do not find
sometimes such operator as
odd_ptr & operator=( odd_ptr_ref<T> rhs ) throw()
{
reset( rhs.r.release() );
return ( *this );
}
which is needed in my code for executing
odd_ptr<int> pi1;
pi1 = f<int>();
Is set of constructors and operators for auto_ptr predefined in C++
standard?
Yes. Quoting from 20.4.5:
// 20.4.5.1 construct/copy/destroy:
explicit auto_ptr(X* p =0) throw();
auto_ptr(auto_ptr&) throw();
template<class Y> auto_ptr(auto_ptr<Y>&) throw();
auto_ptr& operator=(auto_ptr&) throw();
template<class Y> auto_ptr& operator=(auto_ptr<Y>&) throw();
auto_ptr& operator=(auto_ptr_ref<X> r) throw();
??auto_ptr() throw();
// 20.4.5.2 members:
X& operator*() const throw();
X* operator->() const throw();
X* get() const throw();
X* release() throw();
void reset(X* p =0) throw();
// 20.4.5.3 conversions:
auto_ptr(auto_ptr_ref<X>) throw();
template<class Y> operator auto_ptr_ref<Y>() throw();
template<class Y> operator auto_ptr<Y>() throw();
Notes:
- Your destructor isn't declared throw().
- auto_ptr_ref is defined in the surrounding namespace, not nested in class
auto_ptr. In any case, the whole name is odd_ptr::odd_ptr_ref in your case,
with a redundant occurrence of 'odd_ptr'.
- Your odd_ptr_ref is a template, but it is only ever used with the same
template parameter as the surrounding auto_ptr, i.e. the T and U are always
the same. You should be able to drop the template parameter on the
reference type.
- return is not a function, hence no brackets are necessary. While it
doesn't hurt to add brackets around an expression, adding them
unnecessarily IMHO only helps confuse people by making it harder to read.
- reset() checks if the assigned pointer is the same as the one stored.
Since auto_ptr should ensure exclusive ownership, this could only happen in
the case that the pointers are both null. Otherwise, this would be a
programming error. You should rather use assert() than guard against this
symptom of abuse. The only problem I see there is self-assignment.
BTW: There is a glitch in std::auto_ptr. It should not return the pointer
from its release() function. The reason is simple: If you store it e.g. in
a container that assumes ownership, you would probably do this:
cont.push_back(ptr.release());
However, if the push_back() throws e.g. a bad_alloc, you have already
released ownership without anyone taking it. For that, make it not return
anything in order to enforce this order:
cont.push_back(ptr.get());
ptr.release();
A standard-conformant auto_ptr implementation must have this glitch though,
I just wanted to point that out since you're studying this thing.
Uli
--
C++ FAQ: http://parashift.com/c++-faq-lite
Sator Laser GmbH
Gesch??ftsf??hrer: Thorsten F??cking, Amtsgericht Hamburg HR B62 932