21

basic_string の 2 つのスワップ関数 (メンバー関数と名前空間 std の関数) が noexcept で宣言されていないことがわかりました。GCC -4.8 の標準ライブラリでも、最新の C++ ドラフト N3690 でもありません。

一方、move コンストラクターと move 代入演算子はnoexceptで宣言されています。これは、 noexceptスワップ関数を提供できるはずであることを示しています。

質問:スワップ関数がnoexceptで宣言されていない理由は何ですか?

更新:問題は、 static_assert を使用してスワップが実際にnoexceptであることを確認する、独自のスワップ関数内でテンプレート関数を使用したいことです。

struct foo {
    bar_t bar;
    baz_t baz;
    void swap(foo& rhs) noexcept {
        swap_noexcept(bar, rhs.bar);
        swap_noexcept(baz, rhs.baz);
    }
};

ただし、これはスワップ関数がnoexceptで宣言されている場合にのみ機能し、 の場合はそうではありませんbasic_string

4

1 に答える 1

20

C++11 標準の 21.4.6.8 項では、次のように指定されています。

21.4.6.8 basic_string::swap[文字列::スワップ]

void swap(basic_string& s);

1事後条件: *this には s と同じ文字シーケンスが含まれ、s には *this と同じ文字シーケンスが含まれます。

2:無

3複雑さ: 一定時間。

したがって、の不在noexceptは見落としであると結論付けなければなりません。

assign()別の手がかりは、メンバー関数の段落 21.4.6.3 によって与えられます。

basic_string& assign(basic_string&& str) noexcept;

効果: この関数は、 によって制御される文字列を、 によって制御される文字列のコピーを要素とする*this長さの文字列に置き換えます。[注: 有効な実装は. — エンドノート]str.size()strswap(str)

3返品:*this.

swap(str)が の有効な実装であると想定されていてassign()assign()無条件に としてマークされている場合、同様であると想定するnoexceptことは理にかなっています。swap()noexcept

于 2013-05-18T23:02:03.757 に答える