名前空間
変種
操作

std::uninitialized_default_construct_n

From cppreference.com
< cpp‎ | memory
 
 
メモリ管理ライブラリ
(説明用*)
未初期化メモリのアルゴリズム
(C++17)
(C++17)
uninitialized_default_construct_n
(C++17)
(C++17)
制約付き未初期化
メモリアルゴリズム
Cライブラリ

アロケータ
メモリリソース
ガベージコレクションのサポート
(C++11)(C++23まで)
(C++11)(C++23まで)
(C++11)(C++23まで)
(C++11)(C++23まで)
(C++11)(C++23まで)
(C++11)(C++23まで)
未初期化ストレージ
(C++20まで*)
(C++20まで*)
明示的な生存期間管理
 
ヘッダ <memory> で定義
template< class NoThrowForwardIt, class Size >

NoThrowForwardIt uninitialized_default_construct_n

    ( NoThrowForwardIt first, Size count );
(1) (C++17以降)
(C++26 以降 constexpr)
template< class ExecutionPolicy, class NoThrowForwardIt, class Size >

NoThrowForwardIt uninitialized_default_construct_n

    ( ExecutionPolicy&& policy, NoThrowForwardIt first, Size count );
(2) (C++17以降)
1) 未初期化メモリ領域 first + [0count) に、デフォルト初期化によって、あたかも次のようにして、typename std::iterator_traits<NoThrowForwardIt>::value_type 型のオブジェクトを構築します。

for (; count > 0; (void)++first, --count)
    ::new (voidify(*first))
        typename std::iterator_traits<NoThrowForwardIt>::value_type;
return first;

初期化中に例外がスローされた場合、すでに構築されたオブジェクトは未指定の順序で破棄されます。
2) (1) と同じですが、policy に従って実行されます。
このオーバーロードは、以下のすべての条件が満たされた場合にのみオーバーロード解決に参加します。

std::is_execution_policy_v<std::decay_t<ExecutionPolicy>>true です。

(C++20まで)

std::is_execution_policy_v<std::remove_cvref_t<ExecutionPolicy>>true です。

(C++20以降)

目次

[編集] パラメータ

first - 初期化する要素の範囲の先頭
count - 構築する要素の数
policy - 使用する 実行ポリシー
型要件
-
NoThrowForwardItLegacyForwardIterator の要件を満たす必要があります。
-
有効な NoThrowForwardIt のインスタンスを介したインクリメント、代入、比較、間接参照は例外をスローしてはなりません。

[編集] 戻り値

上記の通り。

[編集] 計算量

n に対して線形。

[編集] 例外

テンプレートパラメータ ExecutionPolicy を持つオーバーロードは、次のようにエラーを報告します。

  • アルゴリズムの一部として呼び出された関数の実行が例外をスローし、ExecutionPolicy標準ポリシー のいずれかである場合、std::terminate が呼び出されます。その他の ExecutionPolicy の場合、動作は実装定義です。
  • アルゴリズムがメモリの割り当てに失敗した場合、std::bad_alloc がスローされます。

[編集] 注記

機能テストマクロ 規格 機能
__cpp_lib_raw_memory_algorithms 202411L (C++26) 特殊なメモリアルゴリズムの場合、(1)constexpr です。

[編集] 考えられる実装

template<class NoThrowForwardIt, class Size>
constexpr ForwardIt uninitialized_default_construct_n(NoThrowForwardIt first, Size count)
{
    using T = typename std::iterator_traits<NoThrowForwardIt>::value_type;
    NoThrowForwardIt current = first;
 
    try
    {
        for (; countn > 0; (void) ++current, --count)
            ::new (static_cast<void*>(std::addressof(*current))) T;
        return current;
    }
    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 = std::uninitialized_default_construct_n(first, n);
 
        for (auto it{first}; it != last; ++it)
            std::cout << it->m << '\n';
 
        std::destroy(first, last);
    }
    catch(...)
    {
        std::cout << "Exception!\n";
    }
 
    // For scalar types, uninitialized_default_construct_n
    // generally does not zero-initialize the given uninitialized memory area.
    int v[]{1, 2, 3, 4};
    const int original[]{1, 2, 3, 4};
    std::uninitialized_default_construct_n(std::begin(v), std::size(v));
 
    // An attempt to access v might be an undefined behavior,
    // pending CWG 1997 to be resolved:
    // for (const int i : v)
    //     std::cout << i << ' ';
 
    // The result is unspecified:
    std::cout << (std::memcmp(v, original, sizeof(v)) == 0 ? "un" : "") << "modified\n";
}

実行結果の例

default value
default value
default value
unmodified

[編集] 不具合報告

以下の動作変更を伴う欠陥報告が、以前に公開されたC++標準に遡って適用されました。

DR 適用対象 公開された動作 正しい動作
LWG 3870 C++20 このアルゴリズムは、const ストレージ上にオブジェクトを作成する可能性があります。 禁止されたままです。

[編集] 関連項目

範囲で定義された未初期化メモリ領域に、デフォルト初期化によってオブジェクトを構築します
(関数テンプレート) [編集]
開始位置と個数で定義された未初期化メモリ領域に、値初期化によってオブジェクトを構築します
(関数テンプレート) [編集]
開始位置と個数で定義された未初期化メモリ領域に、デフォルト初期化によってオブジェクトを構築します
(アルゴリズム関数オブジェクト)[編集]
English 日本語 中文(简体) 中文(繁體)