C++1zでは、unique_ptr<T[ ]>と同様に、shared_ptrもテンプレート引数をshared_ptr<T[ ]>もしくはshared_ptr<T[N]>のように指定することで、配列を扱えるようになります。
std::shared_ptr<double[1024]> p1 {new double[1024]}; std::shared_ptr<double[]> p2 {new double[n]}; // 添字アクセス double* p = p1[0];
shared_ptr<T[ ]>はstd::vector<shared_ptr<T>>と比べて、実装として参照カウンタがひとつで済みます。そのため、空間とパフォーマンスはshared_ptr<T[ ]>の方が優れています。
この配列では、以下のような仕様の更新・追加があります:
- コンストラクタが配列も受け取れるような仕様に文面変更 (インタフェースは変わらない)
- 要素型を表すメンバ型として
element_typeを追加- テンプレートパラメータ
Tを直接使用していたところを、配列も考慮した要素型element_typeを使用するように変更
- テンプレートパラメータ
- 配列用に
operator[ ]を追加- テンプレートパラメータが配列型でない場合、この演算子が定義されるかは未規定
std::reinterpret_pointer_cast()関数を追加- 互換性のある配列間の変換で使用する。
shared_ptr<T[ ]> p;をreinterpret_pointer_cast<U[ ]>(p)でshared_ptr<U[ ]>に変換する
- 互換性のある配列間の変換で使用する。
標準にshared_ptrが入る以前、Boostにはshared_arrayという配列を扱う専用のスマートポインタもありましたが、標準ではその設計は採用しませんでした。unique_ptrを先に配列に対応したため、shared_ptrはそちらに合わせて配列対応することになりました。
この配列対応は、Boostでは1.53.0から入っています。
make_shared()の配列対応がN3939で提案されていますが、これはC++1zでは採用されていません。Boostでは1.56.0で対応しています。
参照
- N3640 Extending
shared_ptrto Support Arrays - N3869 Extending
shared_ptrto Support Arrays, Revision 1 - N3920 Extending
shared_ptrto Support Arrays, Revision 2 - P0414R1 Merging
shared_ptrchanges from Library Fundamentals to C++17 - P0497R0 Fixes to
shared_ptrsupport for arrays
お断り
この記事の内容は、C++1zが正式リリースされる際には変更される可能性があります。正式リリース後には、C++日本語リファレンスサイトcpprefjpの以下の階層の下に解説ページを用意する予定です。