Partial ordering of function templates on overloading

Hi all,

This is regarding 14.5.6.2 Partial ordering of function template.

Test case - 1

struct A { };

template struct B {

template int operator*(R&); // #1

};

template<class T, class R> int operator*(T&, R&); // #2

// The declaration of B::operator* is transformed into the equivalent of

// template int operator*(B&, R&); // #1a

int main() {

A a;

B b;

b * a; // calls #1a

}

The above test case works fine as per standards as #1a is more specialized than #2.

However when we tweak the test case in this way:

struct A{};

template struct B
{
template int operator*(R&); // #1
};

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

// The declaration of B::operator* is transformed into the equivalent of
// template int operator*(B
&, R&); // #1a

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

clang throws an error saying:

error: use of overloaded operator ‘*’ is ambiguous (with operand types ‘B’ and ‘A’)

How is partial ordering done in this case? How is the specialization decided for the below mentioned

operator overloading declarations?

template int operator*(B&, R&); // #1a

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

It would be great if someone could explain whether this behavior is correct and more importantly

how clang does partial ordering and judge specialization between two function template overloads?

Thanks,

Rahul

201410091712808_BEI0XT4N.gif