[meta.reflection.extract]

# 21 Metaprogramming library [[meta]](./#meta)

## 21.4 Reflection [[meta.reflection]](meta.reflection#extract)

### 21.4.12 Value extraction [meta.reflection.extract]

[1](#1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L5837)

The extract function template may be used
to extract a value out of a reflection when its type is known[.](#1.sentence-1)

[2](#2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L5841)

The following are defined for exposition only
to aid in the specification of extract[.](#2.sentence-1)

[ð](#itemdecl:1)

`template<class T>
  consteval T extract-ref(info r);      // exposition only
`

[3](#3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L5851)

[*Note [1](#note-1)*:

T is a reference type[.](#3.sentence-1)

â *end note*]

[4](#4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L5856)

*Returns*: If r represents an object O,
then a reference to O[.](#4.sentence-1)

Otherwise, a reference to the object declared, or referred to,
by the variable represented by r[.](#4.sentence-2)

[5](#5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L5863)

*Throws*: meta​::​exception unless

- [(5.1)](#5.1)

r represents a variable or object of type U,

- [(5.2)](#5.2)

is_convertible_v<remove_reference_t<U>(*)[],​ remove_reference_t<​T>(​*)[]> is true,  
and
  [*Note [2](#note-2)*:
  The intent is to allow only qualification conversion from U to T[.](#5.2.sentence-1)
 â *end note*]

- [(5.3)](#5.3)

If r represents a variable,
 then either that variable is usable in constant expressions
 or its lifetime began within the core constant expression currently under evaluation[.](#5.sentence-1)

[ð](#itemdecl:2)

`template<class T>
  consteval T extract-member-or-function(info r);       // exposition only
`

[6](#6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L5888)

*Returns*: 

- [(6.1)](#6.1)

  If T is a pointer type,
 then a pointer value pointing to the function represented by r[.](#6.1.sentence-1)

- [(6.2)](#6.2)

  Otherwise, a pointer-to-member value
 designating the non-static data member or function represented by r[.](#6.2.sentence-1)

[7](#7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L5899)

*Throws*: meta​::​exception unless

- [(7.1)](#7.1)

r represents a non-static data member with type X,
 that is not a bit-field,
 that is a direct member of class C, T and X C​::​* are similar types ([[conv.qual]](conv.qual "7.3.6 Qualification conversions")), and is_convertible_v<X C​::​*, T> is true;

- [(7.2)](#7.2)

r represents an implicit object member function
 with type F or F noexcept that is a direct member of a class C,
 and T is F C​::​*; or

- [(7.3)](#7.3)

r represents a non-member function,
 static member function, or
 explicit object member function
 of function type F or F noexcept,
 and T is F*[.](#7.sentence-1)

[ð](#itemdecl:3)

`template<class T>
  consteval T extract-value(info r);    // exposition only
`

[8](#8)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L5929)

Let U be the type of the value or object that r represents[.](#8.sentence-1)

[9](#9)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L5932)

*Returns*: static_cast<T>([:R:]),
where R is a constant expression of type info such that R == r is true[.](#9.sentence-1)

[10](#10)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L5938)

*Throws*: meta​::​exception unless

- [(10.1)](#10.1)

U is a pointer type, T and U are either similar ([[conv.qual]](conv.qual "7.3.6 Qualification conversions"))
 or both function pointer types, and is_convertible_v<U, T> is true,

- [(10.2)](#10.2)

U is not a pointer type
 and the cv-unqualified types of T and U are the same,

- [(10.3)](#10.3)

U is an array type, T is a pointer type, and
 the value r represents is convertible to T, or

- [(10.4)](#10.4)

U is a closure type, T is a function pointer type, and
 the value that r represents is convertible to T[.](#10.sentence-1)

[ð](#lib:extract)

`template<class T>
  consteval T extract(info r);
`

[11](#11)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L5968)

Let U be remove_cv_t<T>[.](#11.sentence-1)

[12](#12)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L5971)

*Effects*: Equivalent to:if constexpr (is_reference_type(^^T)) {return *extract-ref*<T>(r);} else if constexpr (is_nonstatic_data_member(r) || is_function(r)) {return *extract-member-or-function*<U>(r);} else {return *extract-value*<U>(constant_of(r));}
