[meta.reflection.queries] # 21 Metaprogramming library [[meta]](./#meta) ## 21.4 Reflection [[meta.reflection]](meta.reflection#queries) ### 21.4.7 Reflection queries [meta.reflection.queries] [🔗](#itemdecl:1) `consteval bool has-type(info r); // exposition only ` [1](#1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L3881) *Returns*: true if r represents a value, annotation, object, variable, function whose type does not contain an undeduced placeholder type and that is not a constructor or destructor, enumerator, non-static data member, unnamed bit-field, direct base class relationship, data member description, or function parameter[.](#1.sentence-1) Otherwise, false[.](#1.sentence-2) [🔗](#lib:type_of) `consteval info type_of(info r); ` [2](#2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L3905) *Returns*: - [(2.1)](#2.1) If r represents the ith parameter of a function F, then the ith type in the parameter-type-list of F ([[dcl.fct]](dcl.fct "9.3.4.6 Functions"))[.](#2.1.sentence-1) - [(2.2)](#2.2) Otherwise, if r represents a value, object, variable, function, non-static data member, or unnamed bit-field, then the type of what is represented by r[.](#2.2.sentence-1) - [(2.3)](#2.3) Otherwise, if r represents an annotation, then type_of(constant_of(r))[.](#2.3.sentence-1) - [(2.4)](#2.4) Otherwise, if r represents an enumerator N of an enumeration E, then: * [(2.4.1)](#2.4.1) If E is defined by a declaration D that precedes a point P in the evaluation context and P does not occur within an [*enum-specifier*](dcl.enum#nt:enum-specifier "9.8.1 Enumeration declarations [dcl.enum]") of D, then a reflection of E[.](#2.4.1.sentence-1) * [(2.4.2)](#2.4.2) Otherwise, a reflection of the type of N prior to the closing brace of the [*enum-specifier*](dcl.enum#nt:enum-specifier "9.8.1 Enumeration declarations [dcl.enum]") as specified in [[dcl.enum]](dcl.enum "9.8.1 Enumeration declarations")[.](#2.4.2.sentence-1) - [(2.5)](#2.5) Otherwise, if r represents a direct base class relationship (D,B), then a reflection of B[.](#2.5.sentence-1) - [(2.6)](#2.6) Otherwise, for a data member description (T,N,A,W,NUA) ([[class.mem.general]](class.mem.general "11.4.1 General")), a reflection of the type T[.](#2.6.sentence-1) [3](#3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L3947) *Throws*: meta​::​exception unless*has-type*(r) is true[.](#3.sentence-1) [🔗](#lib:object_of) `consteval info object_of(info r); ` [4](#4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L3959) *Returns*: - [(4.1)](#4.1) If r represents an object, then r[.](#4.1.sentence-1) - [(4.2)](#4.2) Otherwise, if r represents a reference, then a reflection of the object referred to by that reference[.](#4.2.sentence-1) - [(4.3)](#4.3) Otherwise, r represents a variable; a reflection of the object declared by that variable[.](#4.3.sentence-1) [*Example [1](#example-1)*: int x;int& y = x; static_assert(^^x != ^^y); // OK, r and y are different variables so their// reflections compare differentstatic_assert(object_of(^^x) == object_of(^^y)); // OK, because y is a reference// to x, their underlying objects are the same — *end example*] [5](#5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L3984) *Throws*: meta​::​exception unlessr is a reflection representing either - [(5.1)](#5.1) an object with static storage duration ([[basic.stc.general]](basic.stc.general "6.8.6.1 General")), or - [(5.2)](#5.2) a variable that either declares or refers to such an object, and if that variable is a reference R, then either * [(5.2.1)](#5.2.1) R is usable in constant expressions ([[expr.const]](expr.const "7.7 Constant expressions")), or * [(5.2.2)](#5.2.2) the lifetime of R began within the core constant expression currently under evaluation[.](#5.sentence-1) [🔗](#lib:constant_of) `consteval info constant_of(info r); ` [6](#6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4010) Let R be a constant expression of type info such that R == r is true[.](#6.sentence-1) If r represents an annotation, then let C be its underlying constant[.](#6.sentence-2) [7](#7) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4016) *Effects*: Equivalent to:if constexpr (is_annotation(R)) {return C;} else {return reflect_constant([: R :]);} [*Example [2](#example-2)*: constexpr int x = 0;constexpr int y = 0; static_assert(^^x != ^^y); // OK, x and y are different variables,// so their reflections compare differentstatic_assert(constant_of(^^x) == constant_of(^^y)); // OK, both constant_of(^^x) and// constant_of(^^y) represent the value 0static_assert(constant_of(^^x) == reflect_constant(0)); // OK, likewisestruct S { int m; };constexpr S s {42};static_assert(is_object(constant_of(^^s)) && is_object(reflect_object(s)));static_assert(constant_of(^^s) != // OK, template parameter object that is template-argument- reflect_object(s)); // equivalent to s is a different object than sstatic_assert(constant_of(^^s) == constant_of(reflect_object(s))); // OKconsteval info fn() {constexpr int x = 42; return ^^x;}constexpr info r = constant_of(fn()); // error: x is outside its lifetime — *end example*] [8](#8) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4056) *Throws*: meta​::​exception unless either r represents an annotation or[: R :] is a valid[*splice-expression*](expr.prim.splice#nt:splice-expression "7.5.9 Expression splicing [expr.prim.splice]") ([[expr.prim.splice]](expr.prim.splice "7.5.9 Expression splicing"))[.](#8.sentence-1) [🔗](#lib:is_public) `consteval bool is_public(info r); consteval bool is_protected(info r); consteval bool is_private(info r); ` [9](#9) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4074) *Returns*: true if r represents either - [(9.1)](#9.1) a class member or unnamed bit-field that is public, protected, or private, respectively, or - [(9.2)](#9.2) a direct base class relationship (D,B) for which B is, respectively, a public, protected, or private base class of D[.](#9.sentence-1) Otherwise, false[.](#9.sentence-2) [🔗](#lib:is_virtual) `consteval bool is_virtual(info r); ` [10](#10) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4094) *Returns*: true if r represents either a virtual member function or a direct base class relationship (D,B) for which B is a virtual base class of D[.](#10.sentence-1) Otherwise, false[.](#10.sentence-2) [🔗](#lib:is_pure_virtual) `consteval bool is_pure_virtual(info r); consteval bool is_override(info r); ` [11](#11) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4110) *Returns*: true if r represents a member function that is pure virtual or overrides another member function, respectively[.](#11.sentence-1) Otherwise, false[.](#11.sentence-2) [🔗](#lib:is_final) `consteval bool is_final(info r); ` [12](#12) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4123) *Returns*: true if r represents a final class or a final member function[.](#12.sentence-1) Otherwise, false[.](#12.sentence-2) [🔗](#lib:is_deleted) `consteval bool is_deleted(info r); consteval bool is_defaulted(info r); ` [13](#13) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4137) *Returns*: true if r represents a function that is a deleted function ([[dcl.fct.def.delete]](dcl.fct.def.delete "9.6.3 Deleted definitions")) or defaulted function ([[dcl.fct.def.default]](dcl.fct.def.default "9.6.2 Explicitly-defaulted functions")), respectively[.](#13.sentence-1) Otherwise, false[.](#13.sentence-2) [🔗](#lib:is_user_provided) `consteval bool is_user_provided(info r); consteval bool is_user_declared(info r); ` [14](#14) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4153) *Returns*: true if r represents a function that is user-provided or user-declared ([[dcl.fct.def.default]](dcl.fct.def.default "9.6.2 Explicitly-defaulted functions")), respectively[.](#14.sentence-1) Otherwise, false[.](#14.sentence-2) [🔗](#lib:is_explicit) `consteval bool is_explicit(info r); ` [15](#15) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4166) *Returns*: true if r represents a member function that is declared explicit[.](#15.sentence-1) Otherwise, false[.](#15.sentence-2) [*Note [1](#note-1)*: If r represents a member function template that is declared explicit,is_explicit(r) is still false because in general, such queries for templates cannot be answered[.](#15.sentence-3) — *end note*] [🔗](#lib:is_noexcept) `consteval bool is_noexcept(info r); ` [16](#16) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4184) *Returns*: true if r represents a noexcept function type or a function with a non-throwing exception specification ([[except.spec]](except.spec "14.5 Exception specifications"))[.](#16.sentence-1) Otherwise, false[.](#16.sentence-2) [*Note [2](#note-2)*: If r represents a function template that is declared noexcept,is_noexcept(r) is still false because in general, such queries for templates cannot be answered[.](#16.sentence-3) — *end note*] [🔗](#lib:is_bit_field) `consteval bool is_bit_field(info r); ` [17](#17) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4203) *Returns*: true if r represents a bit-field, or if r represents a data member description(T,N,A,W,NUA) ([[class.mem.general]](class.mem.general "11.4.1 General")) for which W is not ⊥[.](#17.sentence-1) Otherwise, false[.](#17.sentence-2) [🔗](#lib:is_enumerator) `consteval bool is_enumerator(info r); consteval bool is_annotation(info r); ` [18](#18) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4220) *Returns*: true if r represents an enumerator or annotation, respectively[.](#18.sentence-1) Otherwise, false[.](#18.sentence-2) [🔗](#lib:is_const) `consteval bool is_const(info r); consteval bool is_volatile(info r); ` [19](#19) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4234) Let T be type_of(r) if *has-type*(r) is true[.](#19.sentence-1) Otherwise, let T be dealias(r)[.](#19.sentence-2) [20](#20) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4238) *Returns*: true if T represents a const or volatile type, respectively, or a const- or volatile-qualified function type, respectively[.](#20.sentence-1) Otherwise, false[.](#20.sentence-2) [🔗](#lib:is_mutable_member) `consteval bool is_mutable_member(info r); ` [21](#21) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4251) *Returns*: true if r represents a mutable non-static data member[.](#21.sentence-1) Otherwise, false[.](#21.sentence-2) [🔗](#lib:is_lvalue_reference_qualified) `consteval bool is_lvalue_reference_qualified(info r); consteval bool is_rvalue_reference_qualified(info r); ` [22](#22) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4265) Let T be type_of(r) if *has-type*(r) is true[.](#22.sentence-1) Otherwise, let T be dealias(r)[.](#22.sentence-2) [23](#23) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4269) *Returns*: true if T represents an lvalue- or rvalue-qualified function type, respectively[.](#23.sentence-1) Otherwise, false[.](#23.sentence-2) [🔗](#lib:has_static_storage_duration) `consteval bool has_static_storage_duration(info r); consteval bool has_thread_storage_duration(info r); consteval bool has_automatic_storage_duration(info r); ` [24](#24) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4286) *Returns*: true if r represents an object or variable that has static, thread, or automatic storage duration, respectively ([[basic.stc]](basic.stc "6.8.6 Storage duration"))[.](#24.sentence-1) Otherwise, false[.](#24.sentence-2) [*Note [3](#note-3)*: It is not possible to have a reflection representing an object or variable having dynamic storage duration[.](#24.sentence-3) — *end note*] [🔗](#lib:has_internal_linkage) `consteval bool has_internal_linkage(info r); consteval bool has_module_linkage(info r); consteval bool has_external_linkage(info r); consteval bool has_c_language_linkage(info r); consteval bool has_linkage(info r); ` [25](#25) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4311) *Returns*: true if r represents a variable, function, type, template, or namespace whose name has internal linkage, module linkage, C language linkage, or any linkage, respectively ([[basic.link]](basic.link "6.7 Program and linkage"))[.](#25.sentence-1) Otherwise, false[.](#25.sentence-2) [🔗](#lib:is_complete_type) `consteval bool is_complete_type(info r); ` [26](#26) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4333) *Returns*: true if is_type(r) is true and there is some point in the evaluation context from which the type represented by dealias(r) is not an incomplete type ([[basic.types]](basic.types "6.9 Types"))[.](#26.sentence-1) Otherwise, false[.](#26.sentence-2) [🔗](#lib:is_enumerable_type) `consteval bool is_enumerable_type(info r); ` [27](#27) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4348) A type T is [*enumerable*](#def:enumerable) from a point P if either - [(27.1)](#27.1) T is a class type complete at point P or - [(27.2)](#27.2) T is an enumeration type defined by a declaration D such that D is reachable from P but P does not occur within an [*enum-specifier*](dcl.enum#nt:enum-specifier "9.8.1 Enumeration declarations [dcl.enum]") of D ([[dcl.enum]](dcl.enum "9.8.1 Enumeration declarations"))[.](#27.sentence-1) [28](#28) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4359) *Returns*: true if dealias(r) represents a type that is enumerable from some point in the evaluation context[.](#28.sentence-1) Otherwise, false[.](#28.sentence-2) [*Example [3](#example-3)*: class S;enum class E;static_assert(!is_enumerable_type(^^S));static_assert(!is_enumerable_type(^^E)); class S {void mfn() {static_assert(is_enumerable_type(^^S)); }static_assert(!is_enumerable_type(^^S));};static_assert(is_enumerable_type(^^S)); enum class E { A = is_enumerable_type(^^E) ? 1 : 2};static_assert(is_enumerable_type(^^E));static_assert(static_cast(E::A) == 2); — *end example*] [🔗](#lib:is_variable) `consteval bool is_variable(info r); ` [29](#29) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4394) *Returns*: true if r represents a variable[.](#29.sentence-1) Otherwise, false[.](#29.sentence-2) [🔗](#lib:is_type) `consteval bool is_type(info r); consteval bool is_namespace(info r); ` [30](#30) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4408) *Returns*: true if r represents an entity whose underlying entity is a type or namespace, respectively[.](#30.sentence-1) Otherwise, false[.](#30.sentence-2) [🔗](#lib:is_type_alias) `consteval bool is_type_alias(info r); consteval bool is_namespace_alias(info r); ` [31](#31) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4423) *Returns*: true if r represents a type alias or namespace alias, respectively[.](#31.sentence-1) Otherwise, false[.](#31.sentence-2) [*Note [4](#note-4)*: A specialization of an alias template is a type alias[.](#31.sentence-3) — *end note*] [🔗](#lib:is_function) `consteval bool is_function(info r); ` [32](#32) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4438) *Returns*: true if r represents a function[.](#32.sentence-1) Otherwise, false[.](#32.sentence-2) [🔗](#lib:is_conversion_function) `consteval bool is_conversion_function(info r); consteval bool is_operator_function(info r); consteval bool is_literal_operator(info r); ` [33](#33) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4454) *Returns*: true if r represents a function that is a conversion function ([[class.conv.fct]](class.conv.fct "11.4.8.3 Conversion functions")), operator function ([[over.oper]](over.oper "12.4 Overloaded operators")), or literal operator ([[over.literal]](over.literal "12.6 User-defined literals")), respectively[.](#33.sentence-1) Otherwise, false[.](#33.sentence-2) [🔗](#lib:is_special_member_function) `consteval bool is_special_member_function(info r); consteval bool is_constructor(info r); consteval bool is_default_constructor(info r); consteval bool is_copy_constructor(info r); consteval bool is_move_constructor(info r); consteval bool is_assignment(info r); consteval bool is_copy_assignment(info r); consteval bool is_move_assignment(info r); consteval bool is_destructor(info r); ` [34](#34) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4485) *Returns*: true if r represents a function that is a special member function ([[special]](special "11.4.4 Special member functions")), a constructor, a default constructor, a copy constructor, a move constructor, an assignment operator, a copy assignment operator, a move assignment operator, or a destructor, respectively[.](#34.sentence-1) Otherwise, false[.](#34.sentence-2) [🔗](#lib:is_function_parameter) `consteval bool is_function_parameter(info r); ` [35](#35) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4506) *Returns*: true if r represents a function parameter[.](#35.sentence-1) Otherwise, false[.](#35.sentence-2) [🔗](#lib:is_explicit_object_parameter) `consteval bool is_explicit_object_parameter(info r); ` [36](#36) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4518) *Returns*: true if r represents a function parameter that is an explicit object parameter ([[dcl.fct]](dcl.fct "9.3.4.6 Functions"))[.](#36.sentence-1) Otherwise, false[.](#36.sentence-2) [🔗](#lib:has_default_argument) `consteval bool has_default_argument(info r); ` [37](#37) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4531) *Returns*: If r represents a parameter P of a function F, then: - [(37.1)](#37.1) If F is a specialization of a templated function T, then true if there exists a declaration D of T that precedes some point in the evaluation context and D specifies a default argument for the parameter of T corresponding to P[.](#37.1.sentence-1) Otherwise, false[.](#37.1.sentence-2) - [(37.2)](#37.2) Otherwise, if there exists a declaration D of F that precedes some point in the evaluation context and D specifies a default argument for P, then true[.](#37.2.sentence-1) Otherwise, false[.](#37.sentence-2) [🔗](#lib:has_ellipsis_parameter) `consteval bool has_ellipsis_parameter(info r); ` [38](#38) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4557) *Returns*: true if r represents a function or function type that has an ellipsis in its parameter-type-list ([[dcl.fct]](dcl.fct "9.3.4.6 Functions"))[.](#38.sentence-1) Otherwise, false[.](#38.sentence-2) [🔗](#lib:is_template) `consteval bool is_template(info r); ` [39](#39) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4570) *Returns*: true if r represents a function template, class template, variable template, alias template, or concept[.](#39.sentence-1) Otherwise, false[.](#39.sentence-2) [40](#40) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4580) [*Note [5](#note-5)*: A template specialization is not a template[.](#40.sentence-1) For example,is_template(​^^std​::​vector) is true but is_template(​^^std​::​vector) is false[.](#40.sentence-2) — *end note*] [🔗](#lib:is_function_template) `consteval bool is_function_template(info r); consteval bool is_variable_template(info r); consteval bool is_class_template(info r); consteval bool is_alias_template(info r); consteval bool is_conversion_function_template(info r); consteval bool is_operator_function_template(info r); consteval bool is_literal_operator_template(info r); consteval bool is_constructor_template(info r); consteval bool is_concept(info r); ` [41](#41) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4611) *Returns*: true if r represents a function template, variable template, class template, alias template, conversion function template, operator function template, literal operator template, constructor template, or concept, respectively[.](#41.sentence-1) Otherwise, false[.](#41.sentence-2) [🔗](#lib:is_value) `consteval bool is_value(info r); consteval bool is_object(info r); ` [42](#42) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4634) *Returns*: true if r represents a value or object, respectively[.](#42.sentence-1) Otherwise, false[.](#42.sentence-2) [🔗](#lib:is_structured_binding) `consteval bool is_structured_binding(info r); ` [43](#43) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4646) *Returns*: true if r represents a structured binding[.](#43.sentence-1) Otherwise, false[.](#43.sentence-2) [🔗](#lib:is_class_member) `consteval bool is_class_member(info r); consteval bool is_namespace_member(info r); consteval bool is_nonstatic_data_member(info r); consteval bool is_static_member(info r); consteval bool is_base(info r); ` [44](#44) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4666) *Returns*: true if r represents a class member, namespace member, non-static data member, static member, or direct base class relationship, respectively[.](#44.sentence-1) Otherwise, false[.](#44.sentence-2) [🔗](#lib:has_default_member_initializer) `consteval bool has_default_member_initializer(info r); ` [45](#45) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4683) *Returns*: true if r represents a non-static data member that has a default member initializer[.](#45.sentence-1) Otherwise, false[.](#45.sentence-2) [🔗](#lib:has_parent) `consteval bool has_parent(info r); ` [46](#46) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4696) *Returns*: - [(46.1)](#46.1) If r represents the global namespace, then false[.](#46.1.sentence-1) - [(46.2)](#46.2) Otherwise, if r represents an entity that has C language linkage ([[dcl.link]](dcl.link "9.12 Linkage specifications")), then false[.](#46.2.sentence-1) - [(46.3)](#46.3) Otherwise, if r represents an entity that has a language linkage other than C++ language linkage, then an implementation-defined value[.](#46.3.sentence-1) - [(46.4)](#46.4) Otherwise, if r represents a type that is neither a class nor enumeration type, then false[.](#46.4.sentence-1) - [(46.5)](#46.5) Otherwise, if r represents an entity or direct base class relationship, then true[.](#46.5.sentence-1) - [(46.6)](#46.6) Otherwise, false[.](#46.6.sentence-1) [🔗](#lib:parent_of) `consteval info parent_of(info r); ` [47](#47) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4729) *Returns*: - [(47.1)](#47.1) If r represents a non-static data member that is a direct member of an anonymous union, or an unnamed bit-field declared within the [*member-specification*](class.mem.general#nt:member-specification "11.4.1 General [class.mem.general]") of such a union, then a reflection representing the innermost enclosing anonymous union[.](#47.1.sentence-1) - [(47.2)](#47.2) Otherwise, if r represents an enumerator, then a reflection representing the corresponding enumeration type[.](#47.2.sentence-1) - [(47.3)](#47.3) Otherwise, if r represents a direct base class relationship (D,B), then a reflection representing D[.](#47.3.sentence-1) - [(47.4)](#47.4) Otherwise, let E be a class, function, or namespace whose class scope, function parameter scope, or namespace scope, respectively, is the innermost such scope that either is, or encloses, the target scope of a declaration of what is represented by r[.](#47.4.sentence-1) * [(47.4.1)](#47.4.1) If E is the function call operator of a closure type for a [*consteval-block-declaration*](dcl.pre#nt:consteval-block-declaration "9.1 Preamble [dcl.pre]") ([[dcl.pre]](dcl.pre "9.1 Preamble")), then parent_of(​parent_of(^^E))[.](#47.4.1.sentence-1) [*Note [6](#note-6)*: In this case, the first parent_of will be the closure type, so the second parent_of is necessary to give the parent of that closure type[.](#47.4.1.sentence-2) — *end note*] * [(47.4.2)](#47.4.2) Otherwise, ^^E[.](#47.4.2.sentence-1) [*Example [4](#example-4)*: struct I { }; struct F : I {union {int o; }; enum N { A };}; constexpr auto ctx = std::meta::access_context::current(); static_assert(parent_of(^^F) == ^^::);static_assert(parent_of(bases_of(^^F, ctx)[0]) == ^^F);static_assert(is_union_type(parent_of(^^F::o)));static_assert(parent_of(^^F::N) == ^^F);static_assert(parent_of(^^F::A) == ^^F::N); — *end example*] [48](#48) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4788) *Throws*: meta​::​exception unlesshas_parent(r) is true[.](#48.sentence-1) [🔗](#lib:dealias) `consteval info dealias(info r); ` [49](#49) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4800) *Returns*: A reflection representing the underlying entity of what r represents[.](#49.sentence-1) [*Example [5](#example-5)*: using X = int;using Y = X;static_assert(dealias(^^int) == ^^int);static_assert(dealias(^^X) == ^^int);static_assert(dealias(^^Y) == ^^int); — *end example*] [50](#50) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4813) *Throws*: meta​::​exception unlessr represents an entity[.](#50.sentence-1) [🔗](#lib:has_template_arguments) `consteval bool has_template_arguments(info r); ` [51](#51) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4825) *Returns*: true if r represents a specialization of a function template, variable template, class template, or an alias template[.](#51.sentence-1) Otherwise, false[.](#51.sentence-2) [🔗](#lib:template_of) `consteval info template_of(info r); ` [52](#52) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4841) *Returns*: A reflection of the template of the specialization represented by r[.](#52.sentence-1) [53](#53) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4845) *Throws*: meta​::​exception unlesshas_template_arguments(r) is true[.](#53.sentence-1) [🔗](#lib:template_arguments_of) `consteval vector template_arguments_of(info r); ` [54](#54) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4857) *Returns*: A vector containing reflections of the template arguments of the template specialization represented by r, in the order in which they appear in the corresponding template argument list[.](#54.sentence-1) For a given template argument A, its corresponding reflection R is determined as follows: - [(54.1)](#54.1) If A denotes a type or type alias, then R is a reflection representing the underlying entity of A[.](#54.1.sentence-1) [*Note [7](#note-7)*: R always represents a type, never a type alias[.](#54.1.sentence-2) — *end note*] - [(54.2)](#54.2) Otherwise, if A denotes a class template, variable template, concept, or alias template, then R is a reflection representing A[.](#54.2.sentence-1) - [(54.3)](#54.3) Otherwise, A is a constant template argument ([[temp.arg.nontype]](temp.arg.nontype "13.4.3 Constant template arguments"))[.](#54.3.sentence-1) Let P be the corresponding template parameter[.](#54.3.sentence-2) * [(54.3.1)](#54.3.1) If P has reference type, then R is a reflection representing the object or function referred to by A[.](#54.3.1.sentence-1) * [(54.3.2)](#54.3.2) Otherwise, if P has class type, then R represents the corresponding template parameter object[.](#54.3.2.sentence-1) * [(54.3.3)](#54.3.3) Otherwise, R is a reflection representing the value of A[.](#54.3.3.sentence-1) [*Example [6](#example-6)*: template struct Pair { };template struct Pair { };template using PairPtr = Pair; static_assert(template_of(^^Pair) == ^^Pair);static_assert(template_of(^^Pair) == ^^Pair);static_assert(template_arguments_of(^^Pair).size() == 2);static_assert(template_arguments_of(^^Pair)[0] == ^^int); static_assert(template_of(^^PairPtr) == ^^PairPtr);static_assert(template_arguments_of(^^PairPtr).size() == 1); struct S { };int i;template class>struct X { };constexpr auto T = ^^X<1, i, S{}, PairPtr>;static_assert(is_value(template_arguments_of(T)[0]));static_assert(is_object(template_arguments_of(T)[1]));static_assert(is_object(template_arguments_of(T)[2]));static_assert(template_arguments_of(T)[3] == ^^PairPtr); — *end example*] [55](#55) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4920) *Throws*: meta​::​exception unlesshas_template_arguments(r) is true[.](#55.sentence-1) [🔗](#lib:parameters_of) `consteval vector parameters_of(info r); ` [56](#56) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4932) *Returns*: - [(56.1)](#56.1) If r represents a function F, then a vector containing reflections of the parameters of F, in the order in which they appear in a declaration of F[.](#56.1.sentence-1) - [(56.2)](#56.2) Otherwise, r represents a function type T; a vector containing reflections of the types in parameter-type-list ([[dcl.fct]](dcl.fct "9.3.4.6 Functions")) of T, in the order in which they appear in the parameter-type-list[.](#56.2.sentence-1) [57](#57) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4946) *Throws*: meta​::​exception unlessr represents a function or a function type[.](#57.sentence-1) [🔗](#lib:variable_of) `consteval info variable_of(info r); ` [58](#58) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4958) *Returns*: The reflection of the parameter variable corresponding to r[.](#58.sentence-1) [59](#59) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4962) *Throws*: meta​::​exception unless - [(59.1)](#59.1) r represents a parameter of a function F and - [(59.2)](#59.2) there is a point P in the evaluation context for which the innermost non-block scope enclosing P is the function parameter scope ([[basic.scope.param]](basic.scope.param "6.4.4 Function parameter scope")) associated with F[.](#59.sentence-1) [🔗](#lib:return_type_of) `consteval info return_type_of(info r); ` [60](#60) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4982) *Returns*: The reflection of the return type of the function or function type represented by r[.](#60.sentence-1) [61](#61) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4987) *Throws*: meta​::​exception unless either r represents a function and *has-type*(r) is true or r represents a function type[.](#61.sentence-1)