[meta.reflection.names] # 21 Metaprogramming library [[meta]](./#meta) ## 21.4 Reflection [[meta.reflection]](meta.reflection#names) ### 21.4.6 Reflection names and locations [meta.reflection.names] [🔗](#lib:has_identifier) `consteval bool has_identifier(info r); ` [1](#1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L3673) *Returns*: - [(1.1)](#1.1) If r represents an entity that has a typedef name for linkage purposes ([[dcl.typedef]](dcl.typedef "9.2.4 The typedef specifier")), then true[.](#1.1.sentence-1) - [(1.2)](#1.2) Otherwise, if r represents an unnamed entity, then false[.](#1.2.sentence-1) - [(1.3)](#1.3) Otherwise, if r represents a class type, then !has_template_arguments(r)[.](#1.3.sentence-1) - [(1.4)](#1.4) Otherwise, if r represents a function, then true if has_template_arguments(r) is false and the function is not a constructor, destructor, operator function, or conversion function[.](#1.4.sentence-1) Otherwise, false[.](#1.4.sentence-2) - [(1.5)](#1.5) Otherwise, if r represents a template, then true if r does not represent a constructor template, operator function template, or conversion function template[.](#1.5.sentence-1) Otherwise, false[.](#1.5.sentence-2) - [(1.6)](#1.6) Otherwise, if r represents the ith parameter of a function F that is an (implicit or explicit) specialization of a templated function T and the ith parameter of the instantiated declaration of T whose template arguments are those of F would be instantiated from a pack, then false[.](#1.6.sentence-1) - [(1.7)](#1.7) Otherwise, if r represents the parameter P of a function F, then let S be the set of declarations, ignoring any explicit instantiations, that precede some point in the evaluation context and that declare either F or a templated function of which F is a specialization; true if * [(1.7.1)](#1.7.1) there is a declaration D in S that introduces a name N for either P or the parameter corresponding to P in the templated function that D declares and * [(1.7.2)](#1.7.2) no declaration in S does so using any name other than N[.](#1.7.sentence-1) Otherwise, false[.](#1.7.sentence-2) [*Example [1](#example-1)*: void fun(int);constexpr std::meta::info r = parameters_of(^^fun)[0];static_assert(!has_identifier(r)); void fun(int x);static_assert(has_identifier(r)); void fun(int x);static_assert(has_identifier(r)); void poison() {void fun(int y);}static_assert(!has_identifier(r)); — *end example*] - [(1.8)](#1.8) Otherwise, if r represents a variable, then false if the declaration of that variable was instantiated from a function parameter pack[.](#1.8.sentence-1) Otherwise, !has_template_arguments(r)[.](#1.8.sentence-2) - [(1.9)](#1.9) Otherwise, if r represents a structured binding, then false if the declaration of that structured binding was instantiated from a structured binding pack[.](#1.9.sentence-1) Otherwise, true[.](#1.9.sentence-2) - [(1.10)](#1.10) Otherwise, if r represents a type alias, then !has_template_arguments(r)[.](#1.10.sentence-1) - [(1.11)](#1.11) Otherwise, if r represents an enumerator, non-static-data member, namespace, or namespace alias, then true[.](#1.11.sentence-1) - [(1.12)](#1.12) Otherwise, if r represents a direct base class relationship, then has_identifier(type_of(r))[.](#1.12.sentence-1) - [(1.13)](#1.13) Otherwise, r represents a data member description (T,N,A,W,NUA) ([[class.mem.general]](class.mem.general "11.4.1 General")); true if N is not ⊥[.](#1.13.sentence-1) Otherwise, false[.](#1.13.sentence-2) [🔗](#lib:identifier_of) `consteval string_view identifier_of(info r); consteval u8string_view u8identifier_of(info r); ` [2](#2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L3782) Let E be UTF-8 for u8identifier_of, and otherwise the ordinary literal encoding[.](#2.sentence-1) [3](#3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L3786) *Returns*: An ntmbs, encoded with E, determined as follows: - [(3.1)](#3.1) If r represents an entity with a typedef name for linkage purposes, then that name[.](#3.1.sentence-1) - [(3.2)](#3.2) Otherwise, if r represents a literal operator or literal operator template, then the [*ud-suffix*](lex.ext#nt:ud-suffix "5.13.9 User-defined literals [lex.ext]") of the operator or operator template[.](#3.2.sentence-1) - [(3.3)](#3.3) Otherwise, if r represents the parameter P of a function F, then let S be the set of declarations, ignoring any explicit instantiations, that precede some point in the evaluation context and that declare either F or a templated function of which F is a specialization; the name that was introduced by a declaration in S for the parameter corresponding to P[.](#3.3.sentence-1) - [(3.4)](#3.4) Otherwise, if r represents an entity, then the identifier introduced by the declaration of that entity[.](#3.4.sentence-1) - [(3.5)](#3.5) Otherwise, if r represents a direct base class relationship, then identifier_of(type_of(r)) or u8identifier_of(type_of(r)), respectively[.](#3.5.sentence-1) - [(3.6)](#3.6) Otherwise, r represents a data member description (T,N,A,W,NUA) ([[class.mem.general]](class.mem.general "11.4.1 General")); a string_view or u8string_view, respectively, containing the identifier N[.](#3.6.sentence-1) [4](#4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L3820) *Throws*: meta​::​exception unlesshas_identifier(r) is true and the identifier that would be returned (see above) is representable by E[.](#4.sentence-1) [🔗](#lib:display_string_of) `consteval string_view display_string_of(info r); consteval u8string_view u8display_string_of(info r); ` [5](#5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L3836) *Returns*: Animplementation-definedstring_view or u8string_view, respectively[.](#5.sentence-1) [6](#6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L3842) *Recommended practice*: Where possible, implementations should return a string suitable for identifying the represented construct[.](#6.sentence-1) [🔗](#lib:source_location_of) `consteval source_location source_location_of(info r); ` [7](#7) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L3855) *Returns*: If r represents a value, a type other than a class type or an enumeration type, the global namespace, or a data member description, then source_location{}[.](#7.sentence-1) Otherwise, animplementation-definedsource_location value[.](#7.sentence-2) [8](#8) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L3867) *Recommended practice*: If r represents an entity with a definition that is reachable from the evaluation context, a value corresponding to a definition should be returned[.](#8.sentence-1)