std::is_move_constructible, std::is_trivially_move_constructible, std::is_nothrow_move_constructible
| Definiert in der Kopfdatei <type_traits> |
||
| template< class T > struct is_move_constructible; |
(1) | (seit C++11) |
| template< class T > struct is_trivially_move_constructible; |
(2) | (seit C++11) |
| template< class T > struct is_nothrow_move_constructible; |
(3) | (seit C++11) |
| Typ-Trait | Der Wert der Member-Konstante value | |
|---|---|---|
T ist ein referenzierbarer Typ |
T ist kein referenzierbarer Typ | |
| (1) | std::is_constructible<T, T&&>::value | false |
| (2) | std::is_trivially_constructible<T, T&&>::value | |
| (3) | std::is_nothrow_constructible<T, T&&>::value | |
Wenn T kein vollständiger Typ ist, (möglicherweise cv-qualifiziert) void oder ein Array unbekannter Größe, ist das Verhalten undefiniert.
Wenn eine Instanziierung einer Vorlage davon direkt oder indirekt von einem unvollständigen Typ abhängt und diese Instanziierung ein anderes Ergebnis liefern könnte, wenn dieser Typ hypothetisch vervollständigt würde, ist das Verhalten undefiniert.
Wenn das Programm Spezialisierungen für eine der auf dieser Seite beschriebenen Vorlagen hinzufügt, ist das Verhalten undefiniert.
Inhalt |
[edit] Hilfsvariablenschablonen
| template< class T > inline constexpr bool is_move_constructible_v = |
(seit C++17) | |
| template< class T > inline constexpr bool is_trivially_move_constructible_v = |
(seit C++17) | |
| template< class T > inline constexpr bool is_nothrow_move_constructible_v = |
(seit C++17) | |
Abgeleitet von std::integral_constant
Member-Konstanten
| value [static] |
true, wenn T verschiebbar ist, andernfalls false(öffentliche statische Member-Konstante) |
Memberfunktionen
| operator bool |
konvertiert das Objekt zu bool, gibt value zurück (öffentliche Memberfunktion) |
| operator() (C++14) |
gibt value zurück (öffentliche Memberfunktion) |
Membertypen
| Typ | Definition |
value_type
|
bool |
type
|
std::integral_constant<bool, value> |
[edit] Mögliche Implementierung
template<class T> struct is_move_constructible : std::is_constructible<T, typename std::add_rvalue_reference<T>::type> {}; template<class T> struct is_trivially_move_constructible : std::is_trivially_constructible<T, typename std::add_rvalue_reference<T>::type> {}; template<class T> struct is_nothrow_move_constructible : std::is_nothrow_constructible<T, typename std::add_rvalue_reference<T>::type> {}; |
[edit] Hinweise
Typen ohne einen Verschiebekonstruktor, aber mit einem Kopierkonstruktor, der Argumente vom Typ const T& akzeptiert, erfüllen std::is_move_constructible.
Verschiebekonstruktoren sind normalerweise noexcept, da sie andernfalls in jedem Code, der eine starke Ausnahme-Garantie bietet, unbrauchbar wären.
In vielen Implementierungen prüft std::is_nothrow_move_constructible auch, ob der Destruktor wirft, da er effektiv noexcept(T(arg)) ist. Dasselbe gilt für std::is_trivially_move_constructible, was in diesen Implementierungen auch verlangt, dass der Destruktor trivial ist: GCC Bug 51452, LWG Issue 2116.
[edit] Beispiel
#include <string> #include <type_traits> struct Ex1 { std::string str; // member has a non-trivial but non-throwing move constructor }; static_assert(std::is_move_constructible_v<Ex1>); static_assert(!std::is_trivially_move_constructible_v<Ex1>); static_assert(std::is_nothrow_move_constructible_v<Ex1>); struct Ex2 { int n; Ex2(Ex2&&) = default; // trivial and non-throwing }; static_assert(std::is_move_constructible_v<Ex2>); static_assert(std::is_trivially_move_constructible_v<Ex2>); static_assert(std::is_nothrow_move_constructible_v<Ex2>); struct NoMove1 { // prevents implicit declaration of default move constructor; // however, the class is still move-constructible because its // copy constructor can bind to an rvalue argument NoMove1(const NoMove1&) {} }; static_assert(std::is_move_constructible_v<NoMove1>); static_assert(!std::is_trivially_move_constructible_v<NoMove1>); static_assert(!std::is_nothrow_move_constructible_v<NoMove1>); struct NoMove2 { // Not move-constructible since the lvalue reference // can't bind to the rvalue argument NoMove2(NoMove2&) {} }; static_assert(!std::is_move_constructible_v<NoMove2>); static_assert(!std::is_trivially_move_constructible_v<NoMove2>); static_assert(!std::is_nothrow_move_constructible_v<NoMove2>); int main() {}
[edit] Defect reports
Die folgenden Verhaltensändernden Fehlerberichte wurden rückwirkend auf zuvor veröffentlichte C++-Standards angewendet.
| DR | angewendet auf | Verhalten wie veröffentlicht | Korrigiertes Verhalten |
|---|---|---|---|
| LWG 2196 | C++11 | das Verhalten war unklar, wenn T&& nicht gebildet werden kann | der erzeugte Wert ist in diesem Fall false |
[edit] Siehe auch
| (C++11)(C++11)(C++11) |
prüft, ob ein Typ einen Konstruktor für spezifische Argumente hat (Klassenvorlage) |
| prüft, ob ein Typ einen Standardkonstruktor hat (Klassenvorlage) | |
| (C++11)(C++11)(C++11) |
prüft, ob ein Typ einen Kopierkonstruktor hat (Klassenvorlage) |
| (C++20) |
gibt an, dass ein Objekt eines Typs per Move konstruiert werden kann (Konzept) |
| (C++11) |
konvertiert das Argument in ein xvalue (Funktionsvorlage) |
| (C++11) |
konvertiert das Argument in ein xvalue, wenn der Move-Konstruktor nicht wirft (Funktionsvorlage) |