<QtTypeTraits> - Qt Type Traits

Fonctionnalités relatives aux traits de type et aux transformations. En savoir plus...

Header: #include <QtTypeTraits>
Since: Qt 6.5

Fonctions

T qExchange(T &obj, U &&newValue)
(since 6.2) std::underlying_type_t<Enum> qToUnderlying(Enum e)

Macros

(since 6.8) QT_NO_QASCONST
(since 6.6) QT_NO_QEXCHANGE

Description détaillée

Documentation des fonctions

[constexpr noexcept(...)] template <typename T, typename U = T> T qExchange(T &obj, U &&newValue)

Remplace la valeur de ` obj ` par ` newValue ` et renvoie l'ancienne valeur de ` obj`.

Il s'agit de l'implémentation par Qt de std::exchange(). Elle ne diffère de std::exchange() que par le fait qu'elle est déjà constexpr avant C++20 et noexcept avant C++23.

Nous vous recommandons vivement d’utiliser std::exchange() lorsque vous n’avez pas besoin des variantes C++20 ou C++23. Vous pouvez désactiver qExchange() en définissant la macro QT_NO_QEXCHANGE.

Voici comment utiliser qExchange() pour implémenter des constructeurs de déplacement :

MyClass(MyClass &&other)
  : m_pointer{qExchange(other.m_pointer, nullptr)},
    m_int{qExchange(other.m_int, 0)},
    m_vector{std::move(other.m_vector)},
    ...

Pour les membres de type classe, nous pouvons utiliser std::move(), car leur constructeur de déplacement fonctionnera correctement. Mais pour les types scalaires tels que les pointeurs bruts ou les types entiers, le déplacement équivaut à une copie, ce qui, en particulier pour les pointeurs, n’est pas le résultat escompté. Nous ne pouvons donc pas utiliser std::move() pour ces types, mais nous pouvons utiliser std::exchange()/qExchange() pour nous assurer que le membre de l’objet source est déjà réinitialisé au moment où nous arrivons à l’initialisation de notre membre de données suivant, ce qui peut s’avérer utile si le constructeur se termine par une exception.

Voici comment utiliser qExchange() pour écrire une boucle qui épuise la collection sur laquelle elle itère :

for (auto &e : qExchange(collection, {})
    doSomethingWith(e);

Ce qui équivaut au code suivant, bien plus verbeux :

{
    auto tmp = std::move(collection);
    collection = {};                    // or collection.clear()
    for (auto &e : tmp)
        doSomethingWith(e);
}                                       // destroys 'tmp'

Cette approche est parfaitement sûre, car la boucle « for » maintient le résultat de qExchange() en vie tant que la boucle s’exécute, ce qui évite de devoir déclarer une variable temporaire. Notez toutefois que qExchange() renvoie un objet non-const, ce qui peut entraîner le détachement des conteneurs Qt.

Remarque : cette fonction est de type « noexcept » lorsque ` std::conjunction_v<std::is_nothrow_move_constructible<T>, std::is_nothrow_assignable<T &, U>> ` est défini comme ` true`.

[constexpr noexcept, since 6.2] template <typename Enum> std::underlying_type_t<Enum> qToUnderlying(Enum e)

Convertit l'e de l'énumérateur en la valeur équivalente exprimée dans le type sous-jacent de son énumération.

Cette fonction a été introduite dans Qt 6.2.

Documentation des macros

[since 6.8] QT_NO_QASCONST

La définition de cette macro rend la fonction qAsConst() indisponible.

Cette macro a été introduite dans Qt 6.8.

Voir également qAsConst.

[since 6.6] QT_NO_QEXCHANGE

La définition de cette macro rend la fonction qExchange() indisponible.

Cette macro a été introduite dans Qt 6.6.

Voir également qExchange.

© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.