[meta.rqmts] # 21 Metaprogramming library [[meta]](./#meta) ## 21.3 Metaprogramming and type traits [[type.traits]](type.traits#meta.rqmts) ### 21.3.2 Requirements [meta.rqmts] [1](#1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L94) A *Cpp17UnaryTypeTrait* describes a property of a type[.](#1.sentence-1) It shall be a class template that takes one template type argument and, optionally, additional arguments that help define the property being described[.](#1.sentence-2) It shall be [*Cpp17DefaultConstructible*](utility.arg.requirements#:Cpp17DefaultConstructible "16.4.4.2 Template argument requirements [utility.arg.requirements]"),[*Cpp17CopyConstructible*](utility.arg.requirements#:Cpp17CopyConstructible "16.4.4.2 Template argument requirements [utility.arg.requirements]"), and publicly and unambiguously derived, directly or indirectly, from its [*base characteristic*](#def:base_characteristic "21.3.2 Requirements [meta.rqmts]"), which is a specialization of the template[integral_constant](meta.help#lib:integral_constant "21.3.4 Helper classes [meta.help]"), with the arguments to the template integral_constant determined by the requirements for the particular property being described[.](#1.sentence-3) The member names of the base characteristic shall not be hidden and shall be unambiguously available in the *Cpp17UnaryTypeTrait*[.](#1.sentence-4) [2](#2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L109) A *Cpp17BinaryTypeTrait* describes a relationship between two types[.](#2.sentence-1) It shall be a class template that takes two template type arguments and, optionally, additional arguments that help define the relationship being described[.](#2.sentence-2) It shall be [*Cpp17DefaultConstructible*](utility.arg.requirements#:Cpp17DefaultConstructible "16.4.4.2 Template argument requirements [utility.arg.requirements]"), [*Cpp17CopyConstructible*](utility.arg.requirements#:Cpp17CopyConstructible "16.4.4.2 Template argument requirements [utility.arg.requirements]"), and publicly and unambiguously derived, directly or indirectly, from its [*base characteristic*](#def:base_characteristic), which is a specialization of the template[integral_constant](meta.help#lib:integral_constant "21.3.4 Helper classes [meta.help]"), with the arguments to the template integral_constant determined by the requirements for the particular relationship being described[.](#2.sentence-3) The member names of the base characteristic shall not be hidden and shall be unambiguously available in the *Cpp17BinaryTypeTrait*[.](#2.sentence-4) [3](#3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L125) A *Cpp17TransformationTrait* modifies a property of a type[.](#3.sentence-1) It shall be a class template that takes one template type argument and, optionally, additional arguments that help define the modification[.](#3.sentence-2) It shall define a publicly accessible nested type named type, which shall be a synonym for the modified type[.](#3.sentence-3) [4](#4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L133) Unless otherwise specified, the behavior of a program that adds specializations for any of the templates specified in [[type.traits]](type.traits "21.3 Metaprogramming and type traits") is undefined[.](#4.sentence-1) [5](#5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L139) Unless otherwise specified, an incomplete type may be used to instantiate a template specified in [[type.traits]](type.traits "21.3 Metaprogramming and type traits")[.](#5.sentence-1) The behavior of a program is undefined if - [(5.1)](#5.1) an instantiation of a template specified in [[type.traits]](type.traits "21.3 Metaprogramming and type traits") directly or indirectly depends on an incompletely-defined object type T, and - [(5.2)](#5.2) that instantiation could yield a different result were T hypothetically completed[.](#5.sentence-2)