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[]
して警告を発したことを思い出すと思います。しかし、それは未定義の動作です。
そのため、呼び出すデストラクタと呼び出すデストラクタの 2 つが必要に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)
残念ながら、これは動的サイズの配列では機能しないため、別の回答を書きます。