[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 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]") && [same_as](concept.same#concept:same_as "18.4.2 Concept same_­as [concept.same]"), info> && [same_as](concept.same#concept:same_as "18.4.2 Concept same_­as [concept.same]")>, info>; template<[reflection_range](#concept:reflection_range "21.4.13 Reflection substitution [meta.reflection.substitute]") R = initializer_list> 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> 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)*: templateauto fn1(); static_assert(!can_substitute(^^fn1, {^^int})); // OKconstexpr info r1 = substitute(^^fn1, {^^int}); // error: fn contains an undeduced// placeholder type for its return typetemplateauto fn2() {static_assert(^^T != ^^int); // static assertion failed during instantiation of fnreturn 0; }constexpr bool r2 = can_substitute(^^fn2, {^^int}); // error: instantiation of body of fn// 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 — *end example*]