// optional<T>版のオーバーロード
void swap(optional& rhs) noexcept(see below); // (1) C++17
constexpr void swap(optional& rhs) noexcept(see below); // (1) C++23
// optional<T&>版のオーバーロード (C++26)
constexpr void swap(optional& rhs) noexcept; // (2) C++26
概要
他のoptionalオブジェクトとデータを入れ替える。
- (1) :
optional<T>の場合。保持している値を入れ替える。 - (2) :
optional<T&>の場合。参照先(内部で保持しているポインタ)を入れ替える。
要件
- (1) : 型
Tがswap可能であること、かつ型Tがムーブ構築可能であること
効果
- (1) :
- (2) :
*thisとrhsが保持する参照先ポインタを入れ替える。すなわち、std::swap(val, rhs.val)(valは参照先を指す説明専用の内部ポインタ)と等価。
例外
- (1) : 効果の項での操作が、任意の例外を送出する可能性がある。ただし、型
Tが、例外を送出しないムーブ構築と、例外を送出しないswap操作ができる場合、この関数は決して例外を送出しない。 - (2) : 投げない。
例外安全性
この関数で例外が送出された場合、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++: ??