名前空間
変種
操作

std::move_if_noexcept

提供: cppreference.com
< cpp‎ | utility
 
 
 
ヘッダ <utility> で定義
template< class T >

typename std::conditional<  
    !std::is_nothrow_move_constructible<T>::value && std::is_copy_constructible<T>::value,
    const T&,
    T&&

>::type move_if_noexcept(T& x) noexcept;
(C++11およびそれ以降)
(C++14以前)
template< class T >

constexpr typename std::conditional<  
    !std::is_nothrow_move_constructible<T>::value && std::is_copy_constructible<T>::value,
    const T&,
    T&&

>::type move_if_noexcept(T& x) noexcept;
(C++14およびそれ以降)

move_if_noexcept は、ムーブコンストラクタが例外を投げない場合、またはコピーコンストラクタがない (ムーブオンリーな) 場合は、引数を指す右辺値参照を取得し、そうでなければ、引数を指す左辺値参照を取得します。 これは一般的にムーブセマンティクスを強い例外保証と組み合わせるために使用されます。

目次

[編集] 引数

x - ムーブまたはコピーされるオブジェクト

[編集] 戻り値

例外保証に応じて std::move(x) または x

[編集] ノート

これは、例えば std::vector::resize によって使用されます。 std::vector::resize は、新しい記憶域を確保し、古い記憶域から新しい記憶域に要素をムーブまたはコピーする必要がある場合があります。 この操作中に例外が発生した場合、 std::vector::resize はその時点までに行ったすべてのことを取り消します。 これはムーブ構築を使用するかコピー構築を使用するかを決めるために std::move_if_noexcept を使用した場合にのみ可能になります。 (ただしコピーコンストラクタが利用可能でない場合は除きます。 その場合はどちらにせよムーブコンストラクタが使用され、強い例外保証は断念されます。)

[編集]

#include <iostream>
#include <utility>
 
struct Bad
{
    Bad() {}
    Bad(Bad&&)  // may throw
    {
        std::cout << "Throwing move constructor called\n";
    }
    Bad(const Bad&) // may throw as well
    {
        std::cout << "Throwing copy constructor called\n";
    }
};
 
struct Good
{
    Good() {}
    Good(Good&&) noexcept // will NOT throw
    {
        std::cout << "Non-throwing move constructor called\n";
    }
    Good(const Good&) noexcept // will NOT throw
    {
        std::cout << "Non-throwing copy constructor called\n";
    }
};
 
int main()
{
    Good g;
    Bad b;
    Good g2 = std::move_if_noexcept(g);
    Bad b2 = std::move_if_noexcept(b);
}

出力:

Non-throwing move constructor called
Throwing copy constructor called

[編集] 計算量

一定。

[編集] 関連項目

(C++11)
関数の引数を転送します
(関数テンプレート) [edit]
(C++11)
右辺値参照を取得します
(関数テンプレート) [edit]