最近、 の使用に遭遇しましたがunique_ptr<T[]>
、その目的は を使用してポインターを削除することだと理解していますdelete[]
。
私を困惑させるのは、それunique_ptr<T[3]>
が無効であるということです (間違っていたら訂正してください)。
テンプレート内の T[] の型は何ですか? T[3] とどう違うのですか? これらは配列なので、同じではないのですか? テンプレート内の型として T[] を使用する他の方法はありますか?
ベストアンサー1
T[]
型です。これは「境界が不明な配列T
」型です。これは不完全な型です。
T[3]
も型です。これは「 3 の配列」型ですT
。 と が異なる型であるのとT[]
同様に、 もとは異なる型です。int
double
テンプレートdefault_delete
は、 という形式の不完全な配列に部分的に特化していますT[]
。ただし、 のような完全な配列型はT[3]
、非常に混乱を招くため禁止されています。unique_ptr
は、配列をその最初の要素へのポインターを通じてのみ処理するため、配列の長さを判断できません。
(メカニズムには技術的な詳細があります。特殊化はdefault_delete<T[3]>
積極的に禁止されていませんが、その呼び出し演算子は を期待するためT(*)[3]
、 から来るポインターとは一般に一致せず、unique_ptr
呼び出しが適切に形成されていたとしても、delete
そのようなポインター上の式は許可されません (= 未定義の動作があります)。いわゆる「配列を削除することはできません」。削除できるのは「サイズが消去されたポインターを介して[]配列を削除」することだけです。)
make_unique
完全な配列型の場合、関数テンプレートはアクティブに削除されることに注意してください。
不思議なことに、make_shared
委員会は別の道を進み、許可する完全な配列型。これを行うには、shared_ptr<T[N]>
一致するものからのみ構築するという前提条件がありますnew T[N]
(ただし、これは一般にはチェックできません)。 (なぜそれが良いアイデアなのか、私にはよくわかりません。)