new[]
is specifically defined to have pointer value despite the array-to-pointer implicit conversion that would kick in anyway.
But I don't think you're out of luck. After all, your example isn't managing a pointer to an int
, it's managing a pointer to an int[10]
. So the ideal way is
MyAutoPtr<int[10]> ptr2(new int[10]);
As Red-Nosed Unicorn mentions, new int[10]
does not create a C-style array. It will if your compiler complies to the C standard as well, but C++ allows C-style arrays to be more than C-style arrays in C. Anyway, new
will create you a C-style array if you ask like this:
MyAutoPtr<int[10]> ptr2(new int [1] [10]);
Unfortunately, delete contents;
will not work even with int (*contents)[10];
. The compiler is allowed to do the right thing: the standard doesn't specify that the array is converted to a pointer as with new
, and I believe I recall GCC substituting delete[]
and emitting a warning. But it's undefined behavior.
So, you will need two destructors, one to call delete
and one to call delete[]
. Since you can't partially specialize a function, the functionality demands a partially specialized helper
template< class T > struct smartptr_dtor {
void operator()( T *ptr ) { delete ptr; }
};
template< class T, size_t N > struct smartptr_dtor< T[N] > {
void operator()( T (*ptr) [N] ) { delete [] ptr; }
};
template< class T >
void proper_delete( T *p ) {
smartptr_dtor< T >()( p );
}
which for some reason I just subjected myself to ;v)
Unfortunately, this doesn't work with dynamic-sized arrays, so I'm going to write up another answer.