Namespaces
Variants

std::uninitialized_default_construct

ja.cppreference.net より
 
 
アルゴリズムライブラリ
制約付きアルゴリズムと範囲に対するアルゴリズム (C++20)
制約付きアルゴリズム、例: ranges::copy, ranges::sort, ...
ソートと関連操作
分割操作
(C++11)    

ソート操作
二分探索操作
(分割された範囲に対する)
集合操作 (ソート済み範囲に対する)
マージ操作 (ソート済み範囲に対する)
ヒープ操作
最小値/最大値操作
(C++11)
(C++17)
辞書順比較操作
順列操作


 
 
ヘッダ <memory>
template< class NoThrowForwardIt >
void uninitialized_default_construct( NoThrowForwardIt first,
                                      NoThrowForwardIt last );
で定義 (1) (C++17 以降)
(C++26 以降 constexpr)
template< class ExecutionPolicy, class NoThrowForwardIt >
void uninitialized_default_construct( ExecutionPolicy&& policy,
                                      NoThrowForwardIt first,
                                      NoThrowForwardIt last );
(2) (C++17 以降)
1) 宛先範囲 [first, last) の要素を デフォルト初期化 により構築します。次のように行われます:

for (; first != last; ++first)
    ::new (voidify(*first))
        typename std::iterator_traits<NoThrowForwardIt>::value_type;

初期化中に例外が発生した場合、既に構築されたオブジェクトは未規定の順序で破棄されます。
2) (1) と同じですが、(1)、policyに従って実行されます。
このオーバーロードは、次の式の値が true である場合にのみオーバーロード解決に参加します:

std::is_execution_policy_v<std::decay_t<ExecutionPolicy>>

(C++20 まで)

std::is_execution_policy_v<std::remove_cvref_t<ExecutionPolicy>>

(C++20 以降)

パラメータ

first, last - 初期化する要素の範囲を定義するイテレータのペア
policy - 使用する実行ポリシー
型要件
-
NoThrowForwardIt は LegacyForwardIterator の要件を満たさなければならない。
-
NoThrowForwardIt の有効なインスタンスを通じたインクリメント、代入、比較、間接参照は例外をスローしてはならない。

例外

2) 実行処理中:
  • 並列化に必要な一時メモリリソースが利用できない場合、std::bad_allocがスローされます。
  • アルゴリズムの引数を介してオブジェクトにアクセス中にキャッチされていない例外がスローされた場合、動作は実行ポリシーによって決まります(標準ポリシー、std::terminateが呼び出されます)。

注釈

機能テスト マクロ 値 標準 機能
__cpp_lib_raw_memory_algorithms 202411L (C++26) constexpr 用 特殊化された <memory> アルゴリズム, (1)

実装例

template<class NoThrowForwardIt>
constexpr void uninitialized_default_construct(NoThrowForwardIt first,
                                               NoThrowForwardIt last)
{
    using Value = typename std::iterator_traits<NoThrowForwardIt>::value_type;
    NoThrowForwardIt current = first;
    try
    {
        for (; current != last; ++current)
        {
            ::new (static_cast<void*>(std::addressof(*current))) Value;
        }
    }
    catch (...)
    {
        std::destroy(first, current);
        throw;
    }
}

例

#include <cstring>
#include <iostream>
#include <memory>
#include <string>
struct S
{
    std::string m{"Default value"};
};
int main()
{
    constexpr int n{3};
    alignas(alignof(S)) unsigned char mem[n * sizeof(S)];
    try
    {
        auto first{reinterpret_cast<S*>(mem)};
        auto last{first + n};
        std::uninitialized_default_construct(first, last);
        for (auto it{first}; it != last; ++it)
            std::cout << it->m << '\n';
        std::destroy(first, last);
    }
    catch (...)
    {
        std::cout << "Exception!\n";
    }
    // スカラー型の場合、uninitialized_default_constructは
    // 一般的に指定された未初期化メモリ領域をゼロフィルしません。
    int v[]{1, 2, 3, 4};
    const int original[]{1, 2, 3, 4};
    std::uninitialized_default_construct(std::begin(v), std::end(v));
    // 未定義動作の可能性あり、CWG 1997の解決待ち
    // for (const int i : v)
    //     std::cout << i << ' ';
    // 結果は未規定
    std::cout <<
        (std::memcmp(v, original, sizeof(v)) == 0 ? "Unmodified\n" : "Modified\n");
}

出力例:

Default value
Default value
Default value
Unmodified

関連項目

開始位置と個数で定義される未初期化メモリ領域で default-initialization によってオブジェクトを構築する
(関数テンプレート)
範囲で定義される未初期化メモリ領域で value-initialization によってオブジェクトを構築する
(関数テンプレート)
範囲で定義される未初期化メモリ領域で default-initialization によってオブジェクトを構築する
(アルゴリズム関数オブジェクト)