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

2025-04-13


532. Member/nonmember operator template partial ordering

Section: 13.7.7.3  [temp.func.order]     Status: C++11     Submitter: Nathan Sidwell     Date: 16 September 2005

[Voted into WP at August, 2010 meeting.]

The Standard does not specify how member and nonmember function templates are to be ordered. This question arises with an example like the following:

    struct A {
        template<class T> void operator<<(T&);
    };

    template<class T> struct B { };
    template<class T> void operator<<(A&, B<T>&);

    int main() {
        A a;
        B<A> b;
        a << b;
    }

The two candidates for “a << b” are:

  1. A::operator<< <B<A> >(B<A>&)
  2. ::operator<< <A>(A&, B<A>&)

How should we treat the implicit this parameter of #1 and the explicit first parameter of #2?

The difference between option 1 and option 2 can be seen in the following example:

    struct A { };

    template<class T> struct B {
        template<typename R> int operator*(R&);   // #1
    };

    template <typename T> int operator*(T&, A&);  // #2

    int main() {
        A a;
        B<A> b;
        b * a;
    }

Should this select #1, select #2, or be ambiguous? Option 1 will select #2, because “A&” is more specialized than “T&”. Option 2 will make this example ambiguous, because “B<A>&” is more specialized than “T&”.

If one were considering two non-member templates,

    template <typename T> int operator*(T&, A&);                 // #2
    template <typename T, typename R> int operator*(B<A>&, R&);  // #3

the current rules would make these unordered. Option 2 thus seems more consistent with this existing behavior.

Notes from the April, 2006 meeting:

The group favored option 2.

Proposed resolution (February, 2010):

Change 13.7.7.3 [temp.func.order] paragraph 3 as follows:

...and substitute it for each occurrence of that parameter in the function type of the template.