<QtTypeTraits> - Qt Type Traits

Fonctionnalité pour les traits de type et les transformations. Plus d'informations...

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 de std::exchange() par Qt. Elle ne diffère de std::exchange() que par le fait qu'elle est constexpr avant C++20 et noexcept avant C++23.

Nous conseillons fortement d'utiliser std::exchange() lorsque vous n'avez pas besoin des variantes C++20 ou C++23. Vous pouvez rendre qExchange() indisponible en définissant la macro QT_NO_QEXCHANGE.

Voici comment utiliser qExchange() pour implémenter les constructeurs de mouvements :

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 d'un type de classe, nous pouvons utiliser std::move(), car leur constructeur de déplacement fera ce qu'il faut. Mais pour les types scalaires tels que les pointeurs bruts ou les entiers, move est la même chose que copy, ce qui, en particulier pour les pointeurs, n'est pas ce que nous attendons. 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 du membre de données suivant, ce qui peut s'avérer utile si le constructeur sort avec une exception.

Voici comment utiliser qExchange() pour écrire une boucle qui consomme la collection qu'elle parcourt :

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

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

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

C'est parfaitement sûr, car la boucle for garde le résultat de qExchange() en vie tant que la boucle tourne, ce qui permet d'économiser la déclaration d'une variable temporaire. Sachez cependant que qExchange() renvoie un objet non-const, de sorte que les conteneurs Qt peuvent se détacher.

Remarque : cette fonction est noexcept lorsque std::conjunction_v<std::is_nothrow_move_constructible<T>, std::is_nothrow_assignable<T &, U>> est true.

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

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

Cette fonction a été introduite dans Qt 6.2.

Documentation sur les macros

[since 6.8] QT_NO_QASCONST

La définition de cette macro supprime la disponibilité de la fonction qAsConst().

Cette macro a été introduite dans Qt 6.8.

Voir aussi qAsConst.

[since 6.6] QT_NO_QEXCHANGE

La définition de cette macro supprime la disponibilité de la fonction qExchange().

Cette macro a été introduite dans Qt 6.6.

Voir aussi 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.