void swap(optional& rhs) noexcept(see below); // C++17
constexpr void swap(optional& rhs) noexcept(see below); // C++23
概要
他のoptional
オブジェクトとデータを入れ替える。
要件
- 型
T
がswap可能であること - 型
T
がムーブ構築可能であること
効果
*this
とrhs
がどちらも有効値を保持している場合、swap(value(), rhs.value())
を呼び出す*this
が有効値を保持しておらず、rhs
が有効値を保持している場合、rhs
が持つ有効値を*this
にムーブ代入し、rhs
をreset()
メンバ関数で無効値の状態にする*this
が有効値を保持しており、rhs
が有効値を保持していない場合、*this
が持つ有効値をrhs
にムーブ代入し、*this
をreset()
メンバ関数で無効値の状態にする*this
とrhs
どちらも有効値を保持していない場合、なにもしない
例外
効果の項での操作が、任意の例外を送出する可能性がある。ただし、型T
が、例外を送出しないムーブ構築と、例外を送出しないswap操作ができる場合、この関数は決して例外を送出しない。
例外安全性
この関数で例外が送出された場合、this->has_value()
とrhs.has_value()
の状態は変わらない。
この関数内で、有効値に対するswap
関数の呼び出しで例外が送出された場合、this->value()
とrhs.value()
は、そのswap
関数の例外安全性が保証する状態となる。
この関数内で、型T
のムーブコンストラクタで例外が送出された場合、this->value()
とrhs.value()
は、そのムーブコンストラクタの例外安全性が保証する状態となる。
例
#include <cassert>
#include <optional>
int main()
{
// 状況1
// 左辺と右辺の両方が有効値を持つ場合
{
std::optional<int> a = 3;
std::optional<int> b = 1;
// aとbを入れ替える
a.swap(b);
assert(a.value() == 1);
assert(b.value() == 3);
}
// 状況2
// 左辺が有効値を持ち、右辺が有効値を持たない場合
{
std::optional<int> a = 3;
std::optional<int> b;
// aとbを入れ替える
a.swap(b);
assert(!a.has_value());
assert(b.has_value());
assert(b.value() == 3);
}
// 状況3
// 左辺が有効値を持たず、右辺が有効値を持つ場合
{
std::optional<int> a;
std::optional<int> b = 3;
// aとbを入れ替える
a.swap(b);
assert(a.has_value());
assert(a.value() == 3);
assert(!b.has_value());
}
// 状況4
// 左辺と右辺の両方が有効値を持たない場合
{
std::optional<int> a;
std::optional<int> b;
// aとbを入れ替える
a.swap(b);
assert(!a.has_value());
assert(!b.has_value());
}
}
出力
バージョン
言語
- C++17
処理系
- Clang: 4.0.1 ✅
- GCC: 7.2 ✅
- ICC: ??
- Visual C++: ??