23 General utilities library [utilities]

23.15 Metaprogramming and type traits [meta]

23.15.4 Unary type traits [meta.unary]

Этот подпункт содержит шаблоны, которые могут использоваться для запроса свойств типа во время компиляции.

Каждый из этих шаблонов должен иметь UnaryTypeTrait базовую характеристику, true_­type если соответствующее условие - вtrueпротивном случае false_­type.

23.15.4.1 Primary type categories [meta.unary.cat]

Категории основных типов соответствуют описаниям, приведенным в разделе[basic.types] стандарта C ++.

Для любого данного типаTрезультат применения одного из этих шаблонов к T и кcvT должен дать одинаковый результат.

[ Note: Для любого данного типаTровно одна из категорий первичного типа имеетvalue член, оцениваемый какtrue. ]end note

Таблица40 - Предикаты категории первичного типа
ШаблонСостояниеКомментарии
template <class T>
struct is_­void;
T являетсяvoid
template <class T>
struct is_­null_­pointer;
T естьnullptr_­t ([basic.fundamental])
template <class T>
struct is_­integral;
T являетсяintegral type
template <class T>
struct is_­floating_­point;
T этоfloating-point type
template <class T>
struct is_­array;
T является типом массива ([basic.compound]) известной или неизвестной степени Шаблон классаarray не является типом массива.
template <class T>
struct is_­pointer;
T этоpointer type Включает указатели на функции, но не указатели на нестатические члены.
template <class T>
struct is_­lvalue_­reference;
T являетсяlvalue reference type
template <class T>
struct is_­rvalue_­reference;
T являетсяrvalue reference type
template <class T>
struct is_­member_­object_­pointer;
T указатель на нестатический член данных
template <class T>
struct is_­member_­function_­pointer;
T указатель на нестатическую функцию-член
template <class T>
struct is_­enum;
T это перечислимый тип ([basic.compound])
template <class T>
struct is_­union;
T тип объединения ([basic.compound])
template <class T>
struct is_­class;
T тип класса, не являющегося объединением ([basic.compound])
template <class T>
struct is_­function;
T это функция type ([basic.compound])

23.15.4.2 Composite type traits [meta.unary.comp]

Эти шаблоны предоставляют удобные композиции категорий первичного типа, соответствующие описаниям, приведенным в разделе[basic.types].

Для любого данного типаTрезультат применения одного из этих шаблонов к T и кcvT должен дать одинаковый результат.

Таблица41 - предикаты категории составного типа
ШаблонСостояниеКомментарии
template <class T>
struct is_­reference;
T ссылка lvalue или ссылка rvalue
template <class T>
struct is_­arithmetic;
T являетсяarithmetic type
template <class T>
struct is_­fundamental;
T этоfundamental type
template <class T>
struct is_­object;
T являетсяobject type
template <class T>
struct is_­scalar;
T этоscalar type
template <class T>
struct is_­compound;
T этоcompound type
template <class T>
struct is_­member_­pointer;
T является указателем на нестатический член данных или нестатическую функцию-член

23.15.4.3 Type properties [meta.unary.prop]

Эти шаблоны предоставляют доступ к некоторым наиболее важным свойствам типов.

Не указано, определяет ли библиотека какие-либо полные или частичные специализации любого из этих шаблонов.

Для всех шаблонов классов,X объявленных в этом подпункте, создание экземпляра этого шаблона с аргументом шаблона, который является специализацией шаблона класса, может привести к неявному созданию экземпляра аргумента шаблона тогда и только тогда, когда семантикаX требует, чтобы аргумент был полным. тип.

В целях определения шаблонов в этом подпункте выражение вызова функцииdeclval<T>() для любого типаT рассматривается как тривиальный вызов функции ([basic.types],[special]), который не являетсяodr-use элементом ofdeclval в контексте соответствующего определения, несмотря на ограничения[declval].

Таблица42 - Предикаты свойств типа
ШаблонСостояниеПредварительные условия
template <class T>
struct is_­const;
T являетсяconst-qualified
template <class T>
struct is_­volatile;
T являетсяvolatile-qualified
template <class T>
struct is_­trivial;
T этоtrivial type remove_­all_­extents_­t<T> должен быть полным типом илиcvvoid.
template <class T>
struct is_­trivially_­copyable;
T этоtrivially copyable type remove_­all_­extents_­t<T> должен быть полным типом или cvvoid.
template <class T>
struct is_­standard_­layout;
T этоstandard-layout type remove_­all_­extents_­t<T> должен быть полным типом илиcvvoid.
template <class T>
struct is_­pod;
T этоPOD type remove_­all_­extents_­t<T> должен быть полным типом илиcvvoid.
template <class T>
struct is_­empty;
T - это тип класса, но не тип объединения, без нестатических членов данных, кроме битовых полей длины 0, без виртуальных функций-членов, без виртуальных базовых классов и без базового класса,B для которогоis_­empty_­v<B> естьfalse. ЕслиT тип класса,T не являющийся объединением, должен быть полным типом.
template <class T>
struct is_­polymorphic;
T этоpolymorphic class ЕслиT тип класса,T не являющийся объединением, должен быть полным типом.
template <class T>
struct is_­abstract;
T являетсяabstract class ЕслиT тип класса,T не являющийся объединением, должен быть полным типом.
template <class T>
struct is_­final;
T - это тип класса, отмеченныйclass-virt-specifier final (Условием[class]). [ Note: Объединение - это тип класса, который можно пометить значкомfinal. ] end note ЕслиT это тип класса, онT должен быть полным типом.
template <class T>
struct is_­aggregate;
T является агрегатным типом ([dcl.init.aggr]) remove_­all_­extents_­t<T> должен быть полным типом илиcvvoid.
template <class T>
struct is_­signed;
Еслиis_­arithmetic_­v<T> естьtrue, тот же результат, что и T(-1) < T(0); иначе,false
template <class T>
struct is_­unsigned;
Еслиis_­arithmetic_­v<T> естьtrue, тот же результат, что и T(0) < T(-1); иначе,false
template <class T, class... Args>
struct is_­constructible;
Для типа функцииT или дляcvvoid типаT, is_­constructible_­v<T, Args...> вfalseпротивном случаеsee below T и все типы в пакете параметровArgs должны быть полными типамиcvvoidили массивами с неизвестной границей.
template <class T>
struct is_­default_­constructible;
is_­constructible_­v<T> естьtrue. T должен быть полным типомcvvoidили массивом с неизвестной границей.
template <class T>
struct is_­copy_­constructible;
Для areferenceable typeTтот же результат, что is_­constructible_­v<T, const T&>и в противном случаеfalse. T должен быть полным типомcvvoidили массивом с неизвестной границей.
template <class T>
struct is_­move_­constructible;
Для ссылочного типаTтот же результат, что is_­constructible_­v<T, T&&>и в противном случаеfalse. T должен быть полным типомcvvoidили массивом с неизвестной границей.
template <class T, class U>
struct is_­assignable;
Выражениеdeclval<T>() =declval<U>() правильно сформировано, если рассматривать его какunevaluated operand. Проверка доступа выполняется, как если бы в контексте, не связанном сT иU. Учитывается только действительность непосредственного контекста выражения присваивания. [ Note: Компиляция выражения может привести к побочным эффектам, таким как создание экземпляров специализаций шаблонов классов и специализаций шаблонов функций, создание неявно определенных функций и т. Д. Такие побочные эффекты не относятся к «непосредственному контексту» и могут привести к неправильному формированию программы. ] end note T иU должны быть полными типамиcvvoidили массивами с неизвестной границей.
template <class T>
struct is_­copy_­assignable;
Для ссылочного типаTтот же результат, что is_­assignable_­v<T&, const T&>и в противном случаеfalse. T должен быть полным типомcvvoidили массивом с неизвестной границей.
template <class T>
struct is_­move_­assignable;
Для ссылочного типаTтот же результат, что is_­assignable_­v<T&, T&&>и в противном случаеfalse. T должен быть полным типомcvvoidили массивом с неизвестной границей.
template <class T, class U>
struct is_­swappable_­with;
Каждое выражениеswap(declval<T>(), declval<U>()) и swap(declval<U>(), declval<T>()) имеет правильный формат, если рассматривать его какunevaluated operand контекст разрешения перегрузки для заменяемых значений ([swappable.requirements]). Проверка доступа выполняется, как если бы в контексте, не связанном сT иU. Учитывается только действительность непосредственного контекстаswap выражений. [ Note: Компиляция выражений может привести к побочным эффектам, таким как создание экземпляров специализаций шаблонов классов и специализаций шаблонов функций, создание неявно определенных функций и т. Д. Такие побочные эффекты не относятся к «непосредственному контексту» и могут привести к неправильному формированию программы. ] end note T иU должны быть полными типами cvvoidили массивами с неизвестной границей.
template <class T>
struct is_­swappable;
Для ссылочного типаTтот же результат, чтоis_­swappable_­with_­v<T&, T&>и в противном случаеfalse. T должен быть полным типом cvvoidили массивом с неизвестной границей.
template <class T>
struct is_­destructible;
ЛибоT это ссылочный тип, либоT полный тип объекта, для которого выражение declval<U&>().~U() правильно сформировано при обработке какunevaluated operand, гдеU есть remove_­all_­extents<T>. T должен быть полным типомcvvoidили массивом с неизвестной границей.
template <class T, class... Args>
struct
is_­trivially_­constructible;
is_­constructible_­v<T,
Args...> is,true и известно, что определение переменной foris_­constructible, как определено ниже, не вызывает никаких нетривиальных операций ([basic.types],[special]).
T и все типы в пакете параметровArgs должны быть полными типами cvvoidили массивами с неизвестной границей.
template <class T>
struct is_­trivially_­default_­constructible;
is_­trivially_­constructible_­v<T> естьtrue. T должен быть полным типом cvvoidили массивом с неизвестной границей.
template <class T>
struct is_­trivially_­copy_­constructible;
Для ссылочного типаTтот же результат, что is_­trivially_­constructible_­v<T, const T&>и в противном случаеfalse. T должен быть полным типом cvvoidили массивом с неизвестной границей.
template <class T>
struct is_­trivially_­move_­constructible;
Для ссылочного типаTтот же результат, что is_­trivially_­constructible_­v<T, T&&>и в противном случаеfalse. T должен быть полным типом cvvoidили массивом с неизвестной границей.
template <class T, class U>
struct is_­trivially_­assignable;
is_­assignable_­v<T, U> есть,true и известно, что присвоение, как определено is_­assignable, не вызывает никакой нетривиальной операции ([basic.types],[special]). T иU должны быть полными типамиcvvoidили массивами с неизвестной границей.
template <class T>
struct is_­trivially_­copy_­assignable;
Для ссылочного типаTтот же результат, что is_­trivially_­assignable_­v<T&, const T&>и в противном случаеfalse. T должен быть полным типом cvvoidили массивом с неизвестной границей.
template <class T>
struct is_­trivially_­move_­assignable;
Для ссылочного типаTтот же результат, что is_­trivially_­assignable_­v<T&, T&&>и в противном случаеfalse. T должен быть полным типом cvvoidили массивом с неизвестной границей.
template <class T>
struct is_­trivially_­destructible;
is_­destructible_­v<T> естьtrue и указанный деструктор, как известно, тривиален. T должен быть полным типом cvvoidили массивом с неизвестной границей.
template <class T, class... Args>
struct is_­nothrow_­constructible;
is_­constructible_­v<T, Args...> is,true а определение переменной foris_­constructible, как определено ниже, не генерирует никаких исключений ([expr.unary.noexcept]). T и все типы в пакете параметровArgs должны быть полными типамиcvvoidили массивами с неизвестной границей.
template <class T>
struct is_­nothrow_­default_­constructible;
is_­nothrow_­constructible_­v<T> естьtrue. T должен быть полным типом cvvoidили массивом с неизвестной границей.
template <class T>
struct is_­nothrow_­copy_­constructible;
Для ссылочного типаTтот же результат, что is_­nothrow_­constructible_­v<T, const T&>и в противном случаеfalse. T должен быть полным типом cvvoidили массивом с неизвестной границей.
template <class T>
struct is_­nothrow_­move_­constructible;
Для ссылочного типаTтот же результат, что is_­nothrow_­constructible_­v<T, T&&>и в противном случаеfalse. T должен быть полным типом cvvoidили массивом с неизвестной границей.
template <class T, class U>
struct is_­nothrow_­assignable;
is_­assignable_­v<T, U> is,true и известно, что присвоение не генерирует никаких исключений ([expr.unary.noexcept]). T иU должны быть полными типамиcvvoidили массивами с неизвестной границей.
template <class T>
struct is_­nothrow_­copy_­assignable;
Для ссылочного типаTтот же результат, что is_­nothrow_­assignable_­v<T&, const T&>и в противном случаеfalse. T должен быть полным типом cvvoidили массивом с неизвестной границей.
template <class T>
struct is_­nothrow_­move_­assignable;
Для ссылочного типаTтот же результат, что is_­nothrow_­assignable_­v<T&, T&&>и в противном случаеfalse. T должен быть полным типом cvvoidили массивом с неизвестной границей.
template <class T, class U>
struct is_­nothrow_­swappable_­with;
is_­swappable_­with_­v<T, U> is,true и известно, что каждоеswap выражение определения не is_­swappable_­with<T, U> вызывает никаких исключений ([expr.unary.noexcept]). T иU должны быть полными типами cvvoidили массивами с неизвестной границей.
template <class T>
struct is_­nothrow_­swappable;
Для ссылочного типаTтот же результат, чтоis_­nothrow_­swappable_­with_­v<T&, T&>и в противном случаеfalse. T должен быть полным типом cvvoidили массивом с неизвестной границей.
template <class T>
struct is_­nothrow_­destructible;
is_­destructible_­v<T> is,true и известно, что указанный деструктор не генерирует никаких исключений ([expr.unary.noexcept]). T должен быть полным типом cvvoidили массивом с неизвестной границей.
template <class T>
struct has_­virtual_­destructor;
T есть виртуальныйdestructor ЕслиT тип класса,T не являющийся объединением, должен быть полным типом.
template <class T>
struct has_­unique_­object_­representations;
Для типа массиваTтот же результат, что has_­unique_­object_­representations_­v<remove_­all_­extents_­t<T>>и в противном случаеsee below. T должен быть полным типомcvvoidили массивом с неизвестной границей.

[Example:

is_const_v<const volatile int>     // true
is_const_v<const int*>             // false
is_const_v<const int&>             // false
is_const_v<int[3]>                 // false
is_const_v<const int[3]>           // true

end example]

[Example:

remove_const_t<const volatile int>  // volatile int
remove_const_t<const int* const>    // const int*
remove_const_t<const int&>          // const int&
remove_const_t<const int[3]>        // int[3]

end example]

[Example:

// Given:
struct P final { };
union U1 { };
union U2 final { };

// the following assertions hold:
static_assert(!is_final_v<int>);
static_assert(is_final_v<P>);
static_assert(!is_final_v<U1>);
static_assert(is_final_v<U2>);

end example]

Условие предиката для специализации шаблона is_­constructible<T, Args...> должно выполняться тогда и только тогда, когда следующее определение переменной будет правильно сформировано для некоторой придуманной переменнойt:

T t(declval<Args>()...);

[ Note: Эти токены никогда не интерпретируются как объявление функции. ] Проверка доступа выполняется, как если бы в контексте, не связанном ни с одним из файлов . Учитывается только действительность непосредственного контекста инициализации переменной. [ Оценка инициализации может привести к побочным эффектам, таким как создание экземпляров специализаций шаблонов классов и специализаций шаблонов функций, создание неявно определенных функций и т. Д. Такие побочные эффекты не относятся к «непосредственному контексту» и могут привести к неправильному формированию программы. ]end noteTArgsNote: end note

Условие предиката для специализации шаблона has_­unique_­object_­representations<T> должно выполняться тогда и только тогда, когда:

  • T легко копируется, и

  • любые два объекта типаT с одинаковым значением имеют одно и то же представление объекта, где два объекта типа массива или класса, не являющегося объединением, считаются имеющими одинаковое значение, если их соответствующие последовательности прямых подобъектов имеют одинаковые значения, и два объекта объединения type считаются имеющими одинаковое значение, если они имеют один и тот же активный член, а соответствующие члены имеют одинаковое значение.

Набор скалярных типов, для которых выполняется это условие, определяется реализацией. [ Note: Если тип имеет биты заполнения, условие не выполняется; в противном случае условие выполняется для целочисленных типов без знака. ]end note