std:: is_move_constructible, std:: is_trivially_move_constructible, std:: is_nothrow_move_constructible
|
Определено в заголовочном файле
<type_traits>
|
||
|
template
<
class
T
>
struct is_move_constructible ; |
(1) | (начиная с C++11) |
|
template
<
class
T
>
struct is_trivially_move_constructible ; |
(2) | (начиная с C++11) |
|
template
<
class
T
>
struct is_nothrow_move_constructible ; |
(3) | (начиная с C++11) |
| Характеристика типа |
Значение константы-члена
value
|
|
|---|---|---|
T
является
ссылочным типом
|
T
не является ссылочным типом
|
|
| (1) | std:: is_constructible < T, T && > :: value | false |
| (2) | std:: is_trivially_constructible < T, T && > :: value | |
| (3) | std:: is_nothrow_constructible < T, T && > :: value | |
Если
T
не является полным типом, (возможно, с cv-квалификаторами)
void
, или массивом неизвестной границы, поведение не определено.
Если создание экземпляра шаблона выше зависит, прямо или косвенно, от неполного типа, и это создание экземпляра может дать другой результат, если бы этот тип был гипотетически завершен, поведение не определено.
Если программа добавляет специализации для любых шаблонов, описанных на этой странице, поведение не определено.
Содержание |
Вспомогательные шаблоны переменных
|
template
<
class
T
>
inline
constexpr
bool
is_move_constructible_v
=
|
(начиная с C++17) | |
|
template
<
class
T
>
inline
constexpr
bool
is_trivially_move_constructible_v
=
|
(начиная с C++17) | |
|
template
<
class
T
>
inline
constexpr
bool
is_nothrow_move_constructible_v
=
|
(начиная с C++17) | |
Унаследовано от std:: integral_constant
Константы-члены
|
value
[static]
|
true
если
T
является конструируемым перемещением,
false
в противном случае
(публичная статическая константа-член) |
Функции-члены
|
operator bool
|
преобразует объект в
bool
, возвращает
value
(публичная функция-член) |
|
operator()
(C++14)
|
возвращает
value
(публичная функция-член) |
Типы-члены
| Тип | Определение |
value_type
|
bool |
type
|
std:: integral_constant < bool , value > |
Возможная реализация
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> {}; |
Примечания
Типы без конструктора перемещения, но с конструктором копирования, который принимает
const
T
&
аргументы, удовлетворяют
std::is_move_constructible
.
Конструкторы перемещения обычно объявляются как noexcept, поскольку в противном случае они непригодны в любом коде, предоставляющем строгую гарантию исключений.
Во многих реализациях
std::is_nothrow_move_constructible
также проверяет, выбрасывает ли деструктор исключения, поскольку это фактически
noexcept
(
T
(
arg
)
)
. То же относится и к
std::is_trivially_move_constructible
, который в этих реализациях также требует, чтобы деструктор был тривиальным:
GCC bug 51452
,
LWG issue 2116
.
Пример
#include <string> #include <type_traits> struct Ex1 { std::string str; // член имеет нетривиальный, но не выбрасывающий исключения конструктор перемещения }; 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; // тривиальный и не выбрасывающий исключения }; 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 { // предотвращает неявное объявление конструктора перемещения по умолчанию; // однако класс все еще перемещаем, потому что его // конструктор копирования может связываться с rvalue-аргументом 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 { // Не перемещаем, поскольку ссылка на lvalue // не может связываться с rvalue-аргументом 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() {}
Отчёты о дефектах
Следующие отчеты об изменениях поведения, влияющие на дефекты, были применены ретроактивно к ранее опубликованным стандартам C++.
| DR | Применяется к | Поведение как опубликовано | Корректное поведение |
|---|---|---|---|
| LWG 2196 | C++11 | поведение было неясным, если T && не может быть сформирован | производимое значение равно false в этом случае |
Смотрите также
|
(C++11)
(C++11)
(C++11)
|
проверяет, имеет ли тип конструктор для определенных аргументов
(шаблон класса) |
|
(C++11)
(C++11)
(C++11)
|
проверяет, имеет ли тип конструктор по умолчанию
(шаблон класса) |
|
(C++11)
(C++11)
(C++11)
|
проверяет, имеет ли тип конструктор копирования
(шаблон класса) |
|
(C++20)
|
указывает, что объект типа может быть сконструирован перемещением
(концепт) |
|
(C++11)
|
преобразует аргумент в xvalue
(шаблон функции) |
|
(C++11)
|
преобразует аргумент в xvalue, если конструктор перемещения не выбрасывает исключений
(шаблон функции) |