This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 115c. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.
2024-09-25
[Accepted as a DR at the March, 2018 (Jacksonville) meeting.]
The late tiebreakers for lvalue-vs-rvalue references and cv-qualification in 13.10.3.5 [temp.deduct.partial] paragraph 9 are applied
If, for a given type, deduction succeeds in both directions (i.e., the types are identical after the transformations above) and both P and A were reference types (before being replaced with the type referred to above):
However, this is based on a false assumption. For example,
template <typename T> struct A { struct typeA { }; struct typeB { }; using convTyA = T (*const &&)(typename A<T>::typeA); using convTyB = T (*const &)(typename A<T>::typeB); operator convTyA(); operator convTyB(); }; template <typename T> void foo(T (*const &&)(typename A<T>::typeA)); template <typename T> int foo(T (*const &)(typename A<T>::typeB)); int main() { return foo<int>(A<int>()); }
(see also issues 1847 and 1157.). We need to decide whether the rule is “deduction succeeds in both directions” or “the types are identical.” The latter seems more reasonable.
Proposed resolution (November, 2017)
Change 13.10.3.5 [temp.deduct.partial] paragraph 9 as follows:
If, for a given type,
deduction succeeds in both directions (i.e.,the types are identical after the transformations above)and both P and A were reference types (before being replaced with the type referred to above):
if the type from the argument template was an lvalue reference and the type from the parameter template was not, the parameter type is not considered to be at least as specialized as the argument type; otherwise,
if the type from the argument template is more cv-qualified than the type from the parameter template (as described above), the parameter type is not considered to be at least as specialized as the argument type.