This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 116a. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.

2024-12-19


495. Overload resolution with template and non-template conversion functions

Section: 12.2.4  [over.match.best]     Status: CD2     Submitter: Nathan Sidwell     Date: 20 Dec 2004

[Voted into WP at July, 2009 meeting.]

The overload resolution rules for ranking a template against a non-template function differ for conversion functions in a surprising way. 12.2.4 [over.match.best] lists four checks, the last three concern this report. For the non-conversion operator case, checks 2 and 3 are applicable, whereas for the conversion operator case checks 3 and 4 are applicable. Checks 2 and 4 concern the ranking of argument and return value conversion sequences respectively. Check 3 concerns only the templatedness of the functions being ranked, and will prefer a non-template to a template. Notice that this check happens after argument conversion sequence ranking, but before return value conversion sequence ranking. This has the effect of always selecting a non-template conversion operator, as the following example shows:

    struct C
    {
      inline operator int () { return 1; }
      template <class T> inline operator T () { return 0; }
    };

    inline long f (long x) { return x; }

    int
    main (int argc, char *argv[])
    {
      return f (C ());
    }

The non-templated C::operator int function will be selected, rather than the apparently better C::operator long<long> instantiation. This is a surprise, and resulted in a bug report where the user expected the template to be selected. In addition some C++ compilers have implemented the overload ranking as if checks 3 and 4 were transposed.

Is this ordering accidental, or is there a rationale?

Notes from the April, 2005 meeting:

The CWG agreed that the template/non-template distinction should be the final tie-breaker.

Proposed resolution (March, 2007):

In the second bulleted list of 12.2.4 [over.match.best] paragraph 1, move the second and third bullets to the end of the list, to read as follows: