std:: is_move_constructible, std:: is_trivially_move_constructible, std:: is_nothrow_move_constructible
|
Definiert im Header
<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 |
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 oben 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 irgendwelche der auf dieser Seite beschriebenen Templates hinzufügt, ist das Verhalten undefiniert.
Inhaltsverzeichnis |
Hilfsvariablen-Templates
|
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) | |
Geerbt von std:: integral_constant
Member-Konstanten
|
value
[static]
|
true
falls
T
move-konstruierbar ist,
false
andernfalls
(öffentliche statische Member-Konstante) |
Member-Funktionen
|
operator bool
|
konvertiert das Objekt zu
bool
, gibt
value
zurück
(öffentliche Member-Funktion) |
|
operator()
(C++14)
|
gibt
value
zurück
(öffentliche Member-Funktion) |
Member-Typen
| Typ | Definition |
value_type
|
bool |
type
|
std:: integral_constant < bool , value > |
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> {}; |
Hinweise
Typen ohne Move-Konstruktor, aber mit einem Kopierkonstruktor, der
const
T
&
Argumente akzeptiert, erfüllen
std::is_move_constructible
.
Move-Konstruktoren sind in der Regel noexcept, da sie sonst in jedem Code, der eine starke Ausnahmesicherheitsgarantie bietet, unbrauchbar wären.
In vielen Implementierungen prüft
std::is_nothrow_move_constructible
auch, ob der Destruktor wirft, da es effektiv
noexcept
(
T
(
arg
)
)
ist. Gleiches gilt für
std::is_trivially_move_constructible
, das in diesen Implementierungen ebenfalls erfordert, dass der Destruktor trivial ist:
GCC bug 51452
,
LWG issue 2116
.
Beispiel
#include <string> #include <type_traits> struct Ex1 { std::string str; // Member hat einen nicht-trivialen aber nicht-werfenden Move-Konstruktor }; 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 und nicht-werfend }; 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 { // verhindert die implizite Deklaration des Standard-Move-Konstruktors; // die Klasse ist jedoch trotzdem move-konstruierbar, weil ihr // Kopierkonstruktor an ein Rvalue-Argument binden kann 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 { // Nicht move-konstruierbar, da die Lvalue-Referenz // nicht an das Rvalue-Argument binden kann 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() {}
Fehlerberichte
Die folgenden verhaltensändernden Fehlerberichte wurden rückwirkend auf zuvor veröffentlichte C++-Standards angewendet.
| DR | Angewendet auf | Verhalten wie veröffentlicht | Korrektes Verhalten |
|---|---|---|---|
| LWG 2196 | C++11 | das Verhalten war unklar, falls T && nicht gebildet werden kann | der erzeugte Wert ist false in diesem Fall |
Siehe auch
|
(C++11)
(C++11)
(C++11)
|
prüft, ob ein Typ einen Konstruktor für bestimmte Argumente besitzt
(Klassentemplate) |
|
(C++11)
(C++11)
(C++11)
|
prüft, ob ein Typ einen Standardkonstruktor besitzt
(Klassentemplate) |
|
(C++11)
(C++11)
(C++11)
|
prüft, ob ein Typ einen Kopierkonstruktor besitzt
(Klassentemplate) |
|
(C++20)
|
spezifiziert, dass ein Objekt eines Typs move-konstruiert werden kann
(Konzept) |
|
(C++11)
|
konvertiert das Argument zu einem xvalue
(Funktionstemplate) |
|
(C++11)
|
konvertiert das Argument zu einem xvalue, wenn der Move-Konstruktor keine Ausnahme wirft
(Funktionstemplate) |