- Title
- Substitution failure and lexical order
- Status
- cd5
- Section
- 13.10.3 [temp.deduct]
- Submitter
- Xiang Fan

Created on **2016-09-06.00:00:00**
last changed **7 months ago**

Date: 2018-04-11.00:00:00

**Proposed resolution, March, 2018:**

Change 13.10.3 [temp.deduct] paragraph 7 as follows:

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:The equivalent substitution in exception specifications is done only when thenoexcept-specifieris instantiated, at which point a program is ill-formed if the substitution results in an invalid type or expression. —end note] [Example: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; //redeclarationtemplate <class T> void h(...) { } void~~h~~x() { f<int>(0); //OK, substituting return type causes deduction to failg<int>(0); //error, substituting parameter type instantiatesA<int> h<int>(0); //ill-formed, no diagnostic required}—

end example]

Date: 2018-06-15.00:00:00

[Accepted as a DR at the June, 2018 (Rapperswil) meeting.]

According to 13.10.3 [temp.deduct] paragraph 7,

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) insidesizeof,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.

However, the same type can be represented in different lexical orders. For example, there is implementation variance on the following example, presumably because of preferring different declarations:

template <class T> struct A { using X = typename T::X; }; template <class T> typename T::X f(typename A<T>::X); template <class T> auto f(typename A<T>::X) -> typename T::X; template <class T> void f(...) { } void h() { f<int>(0); }

History | |||
---|---|---|---|

Date | User | Action | Args |

2020-12-15 00:00:00 | admin | set | status: ready -> cd5 |

2018-04-11 00:00:00 | admin | set | messages: + msg6181 |

2018-04-11 00:00:00 | admin | set | status: drafting -> ready |

2016-09-06 00:00:00 | admin | create |