最終更新日時: 2026年01月06日 12時47分59秒 (JST)
Koichi Murase が更新

履歴 編集

function template
<memory>

# std::make_shared_for_overwrite(C++20)

    namespace std {
      template<class T>
      shared_ptr<T> make_shared_for_overwrite();         // (1)

      template<class T>
      shared_ptr<T> make_shared_for_overwrite(size_t N); // (2)
    }

## 概要

`T`型のオブジェクト、またはその配列への`shared_ptr`を構築し、返却する。

## 効果

型`T`のオブジェクトにメモリを割り当てる（`T`が`U[]`の場合は`U[N]`。`N`はそれぞれのオーバーロードで指定された引数から決定される）。

すべてのオーバーロードにおいて、確保された領域のオブジェクトはデフォルト構築される。

例外が送出された場合、関数は効果がない。

非配列型`U`の（サブ）オブジェクトがこの関数によって初期化されるときは、式`::new(pv) U`によって初期化される。ここで、`pv`は型 `void *`を持ち、型`U`のオブジェクトを保持するための適切なストレージを指す。

配列要素は、アドレスの昇順で初期化される。

戻り値によって管理されるオブジェクトの`lifetime`が終了するか、配列要素の初期化が例外を送出すると、初期化された要素は元の構造の逆の順序で破棄される。

- (1) : このオーバーロードが選択されるとき、`T`は、不明な境界の配列ではない。`T`型のオブジェクトへの`shared_ptr`を返す。
- (2) : このオーバーロードが選択されるとき、`T`は、不明な境界の配列である。型`U[N]`のオブジェクトへの`shared_ptr`を返す。ここで、`U`は`remove_extent_t<T>`である。

## 戻り値

新しく構築されたオブジェクトのアドレスを格納および所有する`shared_ptr`インスタンス。

## 事後条件

`r.get() != 0 && r.use_count() == 1`, ここで、`r` は戻り値である。

## 例外

`bad_alloc`、または`allocate`またはオブジェクトの初期化から送出された例外。

## 備考

メモリの確保にユーザー定義のアロケータを使用したい場合には、 `allocate_shared_for_overwrite()` を使用する。

デフォルト構築においては、トリビアルにデフォルト構築可能な型のオブジェクトは未初期化状態となるため、値を読みだす前に明示的に初期化（overwrite）する必要がある。初期化後の状態が不定になってほしくない場合はこの関数ではなく`make_shared()`を使用すべき。

## 例

    #include <memory>
    #include <iostream>

    int main() {
      std::shared_ptr<int> sp = std::make_shared_for_overwrite<int>();
      if (sp) {
        *sp = 0;  // 必ず初期化する
        std::cout << *sp << std::endl;
      }
    }

### 出力

    0

## バージョン

### 言語

- C++20

### 処理系

- Clang: 10.0.0 現在未対応 ✅
- GCC: 10.0.0 現在未対応 ✅
- Visual C++: ??

## 関連項目

- `std::make_shared()`
- `std::allocate_shared()`
- `std::allocate_shared_for_overwrite()`

## 参照

- P1020R1 Smart pointer creation with default initialization
- P1973R1 Rename "_default_init" Functions