Namespaces
Variants

std::uninitialized_move

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

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


 
 
ヘッダ <memory>
template< class InputIt, class NoThrowForwardIt >
NoThrowForwardIt uninitialized_move( InputIt first, InputIt last,
                                     NoThrowForwardIt d_first );
で定義 (1) (C++17 以上)
(C++26 より constexpr)
template< class ExecutionPolicy,
          class ForwardIt, class NoThrowForwardIt >
NoThrowForwardIt uninitialized_move( ExecutionPolicy&& policy,
                                     ForwardIt first, ForwardIt last,
                                     NoThrowForwardIt d_first );
(2) (C++17 以上)
1) コピー元範囲 d_first の要素から、コピー先範囲の先頭 [first, last) に要素を構築する。あたかも以下のように

for (; first != last; ++d_first, (void) ++first)
    ::new (voidify(*d_first))
        typename std::iterator_traits<NoThrowForwardIt>::value_type(deref-move(*iter));
return d_first;

初期化中に例外が送出された場合、[first, last) 内の一部のオブジェクトは有効だが未規定の状態のままとなり、既に構築されたオブジェクトは未規定の順序で破棄される。
2) (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 以上)


d_first + [0, std::distance(first, last)) が [first, last) と重なる場合、動作は未定義である。

(C++20 以上)

パラメータ

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

戻り値

上記の通り。

例外

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

注記

入力イテレータが右辺値を間接参照する場合、std::uninitialized_moveの動作はstd::uninitialized_copyと同じです。

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

実装例

template<class InputIt, class NoThrowForwardIt>
constexpr NoThrowForwardIt uninitialized_move(InputIt first, InputIt last,
                                              NoThrowForwardIt d_first)
{
    using ValueType = typename std::iterator_traits<NoThrowForwardIt>::value_type;
    auto current = d_first;
    try
    {
        for (; first != last; ++first, (void) ++current)
        {
            auto addr = static_cast<void*>(std::addressof(*current));
            if constexpr (std::is_lvalue_reference_v<decltype(*first)>)
                ::new (addr) ValueType(std::move(*first));
            else
                ::new (addr) ValueType(*first);
        }
        return current;
    }
    catch (...)
    {
        std::destroy(d_first, current);
        throw;
    }
}

例

#include <cstdlib>
#include <iomanip>
#include <iostream>
#include <memory>
#include <string>

void print(auto rem, auto first, auto last)
{
    for (std::cout << rem; first != last; ++first)
        std::cout << std::quoted(*first) << ' ';
    std::cout << '\n';
}

int main()
{
    std::string in[]{"Home", "Work!"};
    print("initially, in: ", std::begin(in), std::end(in));
    
    if (constexpr auto sz = std::size(in);
        void* out = std::aligned_alloc(alignof(std::string), sizeof(std::string) * sz))
    {
        try
        {
            auto first{static_cast<std::string*>(out)};
            auto last{first + sz};
            std::uninitialized_move(std::begin(in), std::end(in), first);
            
            print("after move, in: ", std::begin(in), std::end(in));
            print("after move, out: ", first, last);
            
            std::destroy(first, last);
        }
        catch (...)
        {
            std::cout << "Exception!\n";
        }
        std::free(out);
    }
}

出力例:

initially, in: "Home" "Work!"
after move, in: "" ""
after move, out: "Home" "Work!"

欠陥報告

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

DR 適用先 公開時の動作 正しい動作
LWG 3918 C++17 ムーブ構築は常に実行される
入力イテレータがprvalueを間接参照する場合でも
ムーブ構築なし
この場合

関連項目

未初期化メモリ領域にオブジェクトの範囲をコピーする
(関数テンプレート)
指定された数のオブジェクトを未初期化メモリ領域に移動する
(関数テンプレート)
未初期化メモリ領域にオブジェクトの範囲を移動する
(アルゴリズム関数オブジェクト)