Namespaces
Variants

std::move_if_noexcept

Von de.cppreference.net
 
 
Dienstprogrammbibliothek
Sprachunterstützung
Typunterstützung (grundlegende Typen, RTTI)
Bibliotheks-Feature-Test-Makros (C++20)
Programm-Dienstprogramme
Variadische Funktionen
Coroutine-Unterstützung (C++20)
Vertragsunterstützung (C++26)
Dreifachvergleich
(C++20)
(C++20)(C++20)(C++20)    
(C++20)(C++20)(C++20)

Allgemeine Dienstprogramme
Relationale Operatoren (veraltet in C++20)
Integer-Vergleichsfunktionen
(C++20)(C++20)(C++20)    
(C++20)
Swap- und Typoperationen
(C++14)
(C++11)
(C++11)
(C++11)
(C++17)
Allgemeine Vokabular-Typen
(C++11)
(C++17)
(C++17)
(C++17)
(C++11)
(C++17)
(C++23)



 
Deklariert im Header <utility>
template< class T >
/* see below */ move_if_noexcept( T& x ) noexcept;
(seit C++11)
(constexpr seit C++14)

std::move_if_noexcept erhält eine Rvalue-Referenz auf sein Argument, wenn sein Verschiebekonstruktor keine Ausnahmen auslöst oder wenn kein Kopierkonstruktor vorhanden ist (Nur-Verschiebe-Typ), andernfalls erhält es eine Lvalue-Referenz auf sein Argument. Es wird typischerweise verwendet, um Verschiebesemantik mit einer starken Ausnahmegarantie zu kombinieren.

Der Rückgabetyp von std::move_if_noexcept ist:

  • T&& falls std::is_nothrow_move_constructible<T>::value || !std::is_copy_constructible<T>::value true ist.
  • Andernfalls const T&.

Parameter

x - das zu verschiebende oder zu kopierende Objekt

Rückgabewert

std :: move ( x ) oder x , abhängig von Ausnahmegarantien.

Komplexität

Konstante.

Hinweise

Dies wird beispielsweise verwendet von std::vector::resize , was möglicherweise neuen Speicher allozieren und dann Elemente vom alten Speicher in den neuen Speicher verschieben oder kopieren muss. Wenn während dieser Operation eine Exception auftritt, std::vector::resize macht alles rückgängig, was bis zu diesem Punkt getan wurde, was nur möglich ist, wenn std::move_if_noexcept verwendet wurde, um zu entscheiden, ob Move-Konstruktion oder Copy-Konstruktion verwendet werden soll (es sei denn, der Copy-Konstruktor ist nicht verfügbar, in welchem Fall der Move-Konstruktor ohnehin verwendet wird und die starke Exception-Garantie möglicherweise nicht gewährleistet wird).

Beispiel

#include <iostream>
#include <utility>
struct Bad
{
    Bad() {}
    Bad(Bad&&) // kann werfen
    {
        std::cout << "Throwing move constructor called\n";
    }
    Bad(const Bad&) // kann ebenfalls werfen
    {
        std::cout << "Throwing copy constructor called\n";
    }
};
struct Good
{
    Good() {}
    Good(Good&&) noexcept // wird NICHT werfen
    {
        std::cout << "Non-throwing move constructor called\n";
    }
    Good(const Good&) noexcept // wird NICHT werfen
    {
        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);
}

Ausgabe:

Non-throwing move constructor called
Throwing copy constructor called

Siehe auch

(C++11)
leitet ein Funktionsargument weiter und verwendet den Typ-Template-Parameter, um seine Wertkategorie zu erhalten
(Funktions-Template)
(C++11)
konvertiert das Argument in einen xvalue
(Funktions-Template)