Namespaces
Variants

std::move_if_noexcept

De fr.cppreference.net
 
 
Bibliothèque d’utilitaires
Support linguistique
Support des types (types de base, RTTI)
Macros de test de fonctionnalités de la bibliothèque (C++20)
Utilitaires de programme
Fonctions variadiques
Support des coroutines (C++20)
Support des contrats (C++26)
Comparaison à trois voies
(C++20)
(C++20)(C++20)(C++20)    
(C++20)(C++20)(C++20)

Utilitaires généraux
Opérateurs relationnels (déprécié en C++20)
Fonctions de comparaison d’entiers
(C++20)(C++20)(C++20)    
(C++20)
Opérations d’échange et de type
(C++14)
(C++11)
(C++11)
(C++11)
(C++17)
Types de vocabulaire courants
(C++11)
(C++17)
(C++17)
(C++17)
(C++11)
(C++17)
(C++23)



 
Défini dans l’en‑tête <utility>
template< class T >
/* see below */ move_if_noexcept( T& x ) noexcept;
(depuis C++11)
(constexpr depuis C++14)

std::move_if_noexcept obtient une référence rvalue sur son argument si son constructeur de déplacement ne lève pas d’exception ou s’il n’y a pas de constructeur de copie (type à déplacement seul), sinon obtient une référence lvalue sur son argument. Il est généralement utilisé pour combiner la sémantique de déplacement avec une forte garantie d’exception.

Le type de retour de std::move_if_noexcept est :

  • T&& si std::is_nothrow_move_constructible<T>::value || !std::is_copy_constructible<T>::value est true.
  • Sinon, const T&.

Paramètres

x - l'objet à déplacer ou copier

Valeur de retour

std :: move ( x ) ou x , selon les garanties d'exception.

Complexité

Constante.

Notes

Ceci est utilisé, par exemple, par std::vector::resize , qui peut devoir allouer un nouveau stockage puis déplacer ou copier les éléments de l'ancien stockage vers le nouveau. Si une exception se produit pendant cette opération, std::vector::resize annule tout ce qu'il a fait jusqu'à présent, ce qui n'est possible que si std::move_if_noexcept a été utilisé pour décider d'utiliser la construction par déplacement ou la construction par copie (sauf si le constructeur de copie n'est pas disponible, auquel cas le constructeur de déplacement est utilisé dans tous les cas et la garantie d'exception forte peut être levée).

Exemple

#include <iostream>
#include <utility>
struct Bad
{
    Bad() {}
    Bad(Bad&&) // peut lever une exception
    {
        std::cout << "Throwing move constructor called\n";
    }
    Bad(const Bad&) // peut également lever une exception
    {
        std::cout << "Throwing copy constructor called\n";
    }
};
struct Good
{
    Good() {}
    Good(Good&&) noexcept // ne lèvera PAS d'exception
    {
        std::cout << "Non-throwing move constructor called\n";
    }
    Good(const Good&) noexcept // ne lèvera PAS d'exception
    {
        std::cout << "Non-throwing copy constructor called\n";
    }
};
int main()
{
    Good g;
    Bad b;
    [[maybe_unused]] Good g2 = std::move_if_noexcept(g);
    [[maybe_unused]] Bad b2 = std::move_if_noexcept(b);
}

Sortie :

Non-throwing move constructor called
Throwing copy constructor called

Voir aussi

(C++11)
transmet un argument de fonction et utilise l'argument de type template pour préserver sa catégorie de valeur
(modèle de fonction)
(C++11)
convertit l'argument en xvalue
(modèle de fonction)