C++

C++17 std::shared_ptrの配列対応

  • このエントリーをはてなブックマークに追加
  • Pocket

C++17 テクニックシリーズ

tl;dr

std::shared_ptrが配列に対応する。

un-bounded arrayもbounded arrayも使える(std::shared_ptr<T[]>, std::shared_ptr<T[N]>)。

std::vector<std::shared_ptr<T>>とするよりも空間パフォーマンスに優れる。

std::shared_ptrのリファレンスカウンタが一つで済むためである。

std::make_unique<T[]>はあるが、std::make_shared<T[]>はない(C++20にドラフト入りしている)。

Basic Usage

変数宣言と初期化。

boundedでもun-boundedでもあまり変わらない。

コンストラクタに渡されるときにポインタに変換されてしまうので、

テンプレート引数の推論ができない。

std::shared_ptr: difference in C++17

contents

  • element_typeメンバ型名の追加
  • operator[]メンバ関数の追加
  • std::reinterpret_pointer_castの追加

element_type

従来はTをそのまま使っていたが、配列を考慮してelement_typeメンバが追加される。

operator[]

std::shared_ptr<int[]> p;

などすると

p[1]

で直接配列の要素にアクセスできるようにメンバ関数が用意される。

element_typeが配列型でない場合、このメンバ関数が定義されるかは未規定となる。

std::reinterpret_pointer_cast

std::static_pointer_cast, std::dynamic_pointer_cast, std::const_pointer_castは従来から存在した。

この度、配列対応によって互換性のある配列間でのキャストを行える必要があることからstd::reinterpret_pointer_castが導入される。

libc++ではまだコンストラクタが未実装

とにかく動きません。

clang++では動かないと思えばいい。

[上級者向け解説]

Kona会議で採択された提案が未実装で、std::shared_ptr<Y*>のタイプのコンストラクタがConstraintedになっていない。

そのため、適切にコンストラクタが選択されないのでそもそも初期化できない。

というわけでさっそく遊んでみた

実行してみる|Wandbox

なんの意味があるか分からないが配列版shared_ptrをレンジ操作するためのクラスを作った。

実験なのでconst版のみ。

レンジの他にFold expressionsを濫用してfoldを作った。

Index sequenceとFold expressionsの合わせ技による新魔術。

fold_collect_tの導入によってbinary functionをFold expressionsにアダプトした。

  • このエントリーをはてなブックマークに追加
  • Pocket

コメントを残す

*

This site uses Akismet to reduce spam. Learn how your comment data is processed.