The substitution occurs in all types and expressions that are used in the function
type and in template parameter declarations
. The expressions include not only
constant expressions such as those that appear in array bounds or as nontype
template arguments but also general expressions (i.e., non-constant expressions)
inside
sizeof,
decltype, and other contexts that allow non-constant
expressions
. The substitution proceeds in lexical order and stops when
a condition that causes deduction to fail is encountered
. If substitution into different declarations of the same function template would
cause template instantiations to occur in a different order or not at all,
the program is ill-formed; no diagnostic required
. [
Note 3:
The equivalent substitution in exception specifications is
done only when the
noexcept-specifier is instantiated,
at which point a program is ill-formed
if the substitution results in an invalid type or expression
. —
end note]
[
Example 5:
template <class T> struct A { using X = typename T::X; };
template <class T> typename T::X f(typename A<T>::X);
template <class T> void f(...) { }
template <class T> auto g(typename A<T>::X) -> typename T::X;
template <class T> void g(...) { }
template <class T> typename T::X h(typename A<T>::X);
template <class T> auto h(typename A<T>::X) -> typename T::X;
template <class T> void h(...) { }
void x() {
f<int>(0);
g<int>(0);
h<int>(0);
}
—
end example]