Namespaces
Variants

std:: is_move_constructible, std:: is_trivially_move_constructible, std:: is_nothrow_move_constructible

From cppreference.net
Metaprogramming library
Type traits
Type categories
(C++11)
(C++11) ( DR* )
Type properties
(C++11)
(C++11)
(C++14)
(C++11) (deprecated in C++26)
(C++11) ( until C++20* )
(C++11) (deprecated in C++20)
(C++11)
Type trait constants
Metafunctions
(C++17)
Supported operations
Relationships and property queries
Type modifications
Type transformations
(C++11) (deprecated in C++23)
(C++11) (deprecated in C++23)
(C++11)
(C++11) ( until C++20* ) (C++17)

Compile-time rational arithmetic
Compile-time integer sequences
Определено в заголовочном файле <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 =

is_move_constructible < T > :: value ;
(начиная с C++17)
template < class T >

inline constexpr bool is_trivially_move_constructible_v =

is_trivially_move_constructible < T > :: value ;
(начиная с C++17)
template < class T >

inline constexpr bool is_nothrow_move_constructible_v =

is_nothrow_move_constructible < T > :: value ;
(начиная с 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)
преобразует аргумент в xvalue
(шаблон функции)
преобразует аргумент в xvalue, если конструктор перемещения не выбрасывает исключений
(шаблон функции)