C++1z shared_ptrの配列対応

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で対応しています。

参照

お断り

この記事の内容は、C++1zが正式リリースされる際には変更される可能性があります。正式リリース後には、C++日本語リファレンスサイトcpprefjpの以下の階層の下に解説ページを用意する予定です。