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.