[meta.reflection.substitute]

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

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

### 21.4.13 Reflection substitution [meta.reflection.substitute]

[ð](#concept:reflection_range)

`template<class R>
concept [reflection_range](#concept:reflection_range "21.4.13 Reflection substitution [meta.reflection.substitute]") =
  ranges::[input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]")<R> &&
  [same_as](concept.same#concept:same_as "18.4.2 Concept same_­as [concept.same]")<ranges::range_value_t<R>, info> &&
  [same_as](concept.same#concept:same_as "18.4.2 Concept same_­as [concept.same]")<remove_cvref_t<ranges::range_reference_t<R>>, info>;

template<[reflection_range](#concept:reflection_range "21.4.13 Reflection substitution [meta.reflection.substitute]") R = initializer_list<info>>
  consteval bool [can_substitute](#lib:can_substitute "21.4.13 Reflection substitution [meta.reflection.substitute]")(info templ, R&& arguments);
`

[1](#1)

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

Let Z be the template represented by templ and let Args... be a sequence of prvalue constant expressions
that compute the reflections held by the elements of arguments,
in order[.](#1.sentence-1)

[2](#2)

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

*Returns*: true if Z<[:Args:]...> is a valid [*template-id*](temp.names#nt:template-id "13.3 Names of template specializations [temp.names]") ([[temp.names]](temp.names "13.3 Names of template specializations"))
that does not name a function
whose type contains an undeduced placeholder type[.](#2.sentence-1)

Otherwise, false[.](#2.sentence-2)

[3](#3)

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

*Throws*: meta​::​exception unlesstempl represents a template,
and every reflection in arguments represents a construct
usable as a template argument ([[temp.arg]](temp.arg "13.4 Template arguments"))[.](#3.sentence-1)

[4](#4)

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

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

If forming Z<[:Args:]...> leads to a failure
outside of the immediate context,
the program is ill-formed[.](#4.sentence-1)

â *end note*]

[ð](#lib:substitute)

`template<[reflection_range](#concept:reflection_range "21.4.13 Reflection substitution [meta.reflection.substitute]") R = initializer_list<info>>
  consteval info substitute(info templ, R&& arguments);
`

[5](#5)

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

Let Z be the template represented by templ and let Args... be a sequence of prvalue constant expressions
that compute the reflections held by the elements of arguments,
in order[.](#5.sentence-1)

[6](#6)

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

*Returns*: ^^Z<[:Args:]...>[.](#6.sentence-1)

[7](#7)

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

*Throws*: meta​::​exception unlesscan_substitute(templ, arguments) is true[.](#7.sentence-1)

[8](#8)

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

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

If forming Z<[:Args:]...> leads to a failure outside of the immediate context,
the program is ill-formed[.](#8.sentence-1)

â *end note*]

[9](#9)

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

[*Example [1](#example-1)*: template<class T>auto fn1();

static_assert(!can_substitute(^^fn1, {^^int})); // OKconstexpr info r1 = substitute(^^fn1, {^^int}); // error: fn<int> contains an undeduced// placeholder type for its return typetemplate<class T>auto fn2() {static_assert(^^T != ^^int); // static assertion failed during instantiation of fn<int>return 0; }constexpr bool r2 = can_substitute(^^fn2, {^^int}); // error: instantiation of body of fn<int>// is needed to deduce return type â *end example*]

[10](#10)

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

[*Example [2](#example-2)*: consteval info to_integral_constant(unsigned i) {return substitute(^^integral_constant, {^^unsigned, reflect_constant(i)});}constexpr info r = to_integral_constant(2); // OK, r represents the type// integral_constant<unsigned, 2> â *end example*]
