I was at work, writing the Comparators in a function (to move later, when I decided where was best), and noticed this peculiarity. I thought about it for a while, and reali
Your code is fine in C++11; there was a restriction about using local types as template arguments in C++03.
In C++03, template arguments could not have internal linkage:
[C++03: 14.6.4.2/1]:
For a function call that depends on a template parameter, if the function name is an unqualified-id but not a template-id, the candidate functions are found using the usual lookup rules (3.4.1, 3.4.2) except that:
- For the part of the lookup using unqualified name lookup (3.4.1), only function declarations with external linkage from the template definition context are found.
- For the part of the lookup using associated namespaces (3.4.2), only function declarations with external linkage found in either the template definition context or the template instantiation context are found.
[..]
This was changed (issue #561: "Internal linkage functions in dependent name lookup") in C++11:
[C++11: C.2.6]:
14.6.4.2
Change: Allow dependent calls of functions with internal linkage
Rationale: Overly constrained, simplify overload resolution rules.
resulting in:
[C++11: 14.6.4.2/1]:
For a function call that depends on a template parameter, the candidate functions are found using the usual lookup rules (3.4.1, 3.4.2, 3.4.3) except that:
- For the part of the lookup using unqualified name lookup (3.4.1) or qualified name lookup (3.4.3), only function declarations from the template definition context are found.
- For the part of the lookup using associated namespaces (3.4.2), only function declarations found in either the template definition context or the template instantiation context are found.
[..]
(Spot the missing "with external linkage" qualification.)
Since your main()::ComparitorInner&
has internal linkage, and the instantiation of std::sort
requires this type to be a template parameter (albeit deduced), your code is only valid in C++11.