new[]
специально определяется как значение указателя, несмотря на неявное преобразование массива в указатель, которое в любом случае сработает.
Но я не думаю, что вам не повезло. В конце концов, ваш пример не управляет указателем на int
, он управляет указателем на int[10]
. Итак, идеальный способ
MyAutoPtr<int[10]> ptr2(new int[10]);
Как упоминает Red-Nosed Unicorn, new int[10]
не создает массив C-стиля. Так и будет, если ваш компилятор также соответствует стандарту C, но C++ допускает, чтобы массивы в стиле C были больше, чем массивы в стиле C в C. В любом случае, new
создаст вам массив в стиле C, если вы спросите так:
MyAutoPtr<int[10]> ptr2(new int [1] [10]);
К сожалению, delete contents;
не будет работать даже с int (*contents)[10];
. Компилятору разрешено поступать правильно: в стандарте не указано, что массив преобразуется в указатель, как в случае с new
, и, кажется, я припоминаю, что GCC подставил delete[]
и выдал предупреждение. Но это неопределенное поведение.
Итак, вам понадобятся два деструктора, один для вызова delete
, а другой для вызова delete[]
. Поскольку вы не можете частично специализировать функцию, функциональность требует частично специализированного помощника.
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 );
}
которому по какой-то причине я только что подвергся ;v)
К сожалению, это не работает с массивами динамического размера, поэтому я напишу еще один ответ.
person
Potatoswatter
schedule
07.04.2010
array
внутри самого языка :( - person Matthieu M.   schedule 07.04.2010