<QtTypeTraits> - Qt Type Traits
型特性と変換のための機能。詳細...
Header: | #include <QtTypeTraits> |
Since: | Qt 6.5 |
関数
T | qExchange(T &obj, U &&newValue) |
(since 6.2) std::underlying_type_t<Enum> | qToUnderlying(Enum e) |
マクロ
(since 6.8) | QT_NO_QASCONST |
(since 6.6) | QT_NO_QEXCHANGE |
関数 ドキュメンテーション
[constexpr noexcept(...)]
template <typename T, typename U = T> T qExchange(T &obj, U &&newValue)
obj の値をnewValue に置き換え、古い値obj を返します。
これは Qt による std::exchange() の実装です。std::exchange()との違いは、C++20以前では既にconstexpr
、C++23以前では既にnoexceptとなっている点のみです。
C++20 や C++23 の亜種を必要としない場合は、std::exchange() を使用することを強くお勧めします。QT_NO_QEXCHANGE マクロを定義することで、qExchange() を使用できないようにすることができます。
以下は、qExchange() を使用して移動コンストラクタを実装する方法です:
MyClass(MyClass &&other) : m_pointer{qExchange(other.m_pointer, nullptr)}, m_int{qExchange(other.m_int, 0)}, m_vector{std::move(other.m_vector)}, ...
クラス型のメンバについては、std::move()を使用することができる。しかし、未加工のポインタや整数型のようなスカラー型では、moveはcopyと同じであり、特にポインタでは期待されたものではありません。しかし、std::exchange()/qExchange()を使えば、コンストラクタが例外で終了した場合に便利なように、次のデータ・メンバの初期化までにソース・オブジェクトのメンバがすでにリセットされていることを確認できる。
以下は、qExchange()を使用して、反復処理するコレクションを消費するループを記述する方法です:
for (auto &e : qExchange(collection, {}) doSomethingWith(e);
これは次のコードと同じで、もっと冗長なコードです:
{ auto tmp = std::move(collection); collection = {}; // or collection.clear() for (auto &e : tmp) doSomethingWith(e); } // destroys 'tmp'
これは完全に安全である。forループはループが実行される限りqExchange()の結果を保持し、一時変数の宣言を保存するからである。ただし、qExchange() は const でないオブジェクトを返すので、Qt コンテナが切り離される可能性があることに注意してください。
注意: この関数は、"std::conjunction_v<std::is_nothrow_move_constructible<T>, std::is_nothrow_assignable<T &, U>" が真であっても例外をスローしません。
[constexpr noexcept, since 6.2]
template <typename Enum> std::underlying_type_t<Enum> qToUnderlying(Enum e)
列挙子e を、その列挙子の基底型で表現される同等の値に変換します。
この関数は Qt 6.2 で導入されました。
本ドキュメントに含まれる文書の著作権は、それぞれの所有者に帰属します。 本書で提供されるドキュメントは、Free Software Foundation が発行したGNU Free Documentation License version 1.3に基づいてライセンスされています。 Qtおよびそれぞれのロゴは、フィンランドおよびその他の国におけるThe Qt Company Ltd.の 商標です。その他すべての商標は、それぞれの所有者に帰属します。