その1に引き続き、C++14の標準ライブラリに入った、小さな変更を紹介していきます。
weak_ptrがムーブに対応した
C++14では、弱参照スマートポインタのstd::weak_ptrクラスに、以下のコンストラクタと、
weak_ptr(weak_ptr&& r) noexcept; template <class Y> weak_ptr(weak_ptr<Y>&& r) noexcept;
以下の代入演算子が追加されました。
weak_ptr& operator=(weak_ptr&& r) noexcept; template <class Y> weak_ptr& operator=(weak_ptr<Y>&& r) noexcept;
これまで、weak_ptrはコピーはできたので、既存コードに影響はありません。
細かいnoexceptの付け忘れ対応
std::integral_constantクラスの、テンプレートパラメータの型Tへの変換演算子にnoexceptが追加されました。
constexpr operator value_type() { return value; } // C++11 constexpr operator value_type() noexcept { return value; } // C++14
<ios>ヘッダの以下の関数に、noexceptが追加されました。
iostream_category()関数 : 入出力のエラーカテゴリオブジェクトを作って返す。
namespace std { const error_category& iostream_category(); // C++11 const error_category& iostream_category() noexcept; // C++14 }
make_error_code()関数 : 入出力関係のエラーコードを作って返す。
namespace std { error_code make_error_code(io_errc e); // C++11 error_code make_error_code(io_errc e) noexcept; // C++14 }
make_error_condition()関数 : 入出力関係のエラーコードに紐づく情報を、作って返す。
namespace std { error_condition make_error_condition(io_errc e); // C++11 error_condition make_error_condition(io_errc e) noexcept; // C++14 }
非メンバ関数版の組み込み配列用begin()とend()に、noexceptが追加されました。
namespace std { template <class T, size_t N> T* begin(T (&array)[N]); // C++11 template <class T, size_t N> constexpr T* begin(T (&array)[N]) noexcept; // C++14 }
namespace std { template <class T, size_t N> T* end(T (&array)[N]); // C++11 template <class T, size_t N> constexpr T* end(T (&array)[N]) noexcept; // C++14 }
future_errcの開始値が0ではなくなった
C++11で<future>ヘッダに追加された、future/promise関係のエラー値列挙型std::future_errcですが、列挙値が実装定義になりました。
C++11:
namespace std { // C++11 enum class future_errc { broken_promise, future_already_retrieved, promise_already_satisfied, no_state }; }
C++14:
namespace std { enum class future_errc { broken_promise = implementation-defined, future_already_retrieved = implementation-defined, promise_already_satisfied = implementation-defined, no_state = implementation-defined }; }
この変更は、std::future_errcの値をstd::error_codeオブジェクトに入れたときに、開始値が0だと困るからです。
開始値broken_promiseは、正常値ではなくエラー値です。これが0だと困るのは、std::error_codeクラスのoperator bool()が、以下の仕様になっていることです。
explicit operator bool() const noexcept; 戻り値: return value() != 0
つまり、0を正常値、0以外をエラー値としています。
そのため、C++11のbroken_promiseをstd::error_codeに設定すると、エラー値なのに正常値と見なされてしまいます。
C++14のこの変更で、std::future_errcのいずれの値も0以外になります。
今日はこれまで
さらに続きます。