Consider this example
struct A { };
template<class T> struct B {
template<class R> int operator*(R&); // #1
};
template<class T, class R> int operator*(T&, R&); // #2
The partial ordering will apply to #1
and #2
to select the best viable function template.
Two sets of types are used to determine the partial ordering. For each of the templates involved there is the original function type and the transformed function type. The deduction process uses the transformed type as the argument template and the original type of the other template as the parameter template. This process is done twice for each type involved in the partial ordering comparison: once using the transformed template-1 as the argument template and template-2 as the parameter template and again using the transformed template-2 as the argument template and template-1 as the parameter template.
Partial ordering selects which of two function templates is more specialized than the other by transforming each template in turn (see next paragraph)
To produce the transformed template, for each type, non-type, or template template parameter (including template parameter packs thereof) synthesize a unique type, value, or class template respectively and substitute it for each occurrence of that parameter in the function type of the template. [ Note: The type replacing the placeholder in the type of the value synthesized for a non-type template parameter is also a unique synthesized type. — end note ] If only one of the function templates M is a non-static member of some class A, M is considered to have a new first parameter inserted in its function parameter list. Given cv as the cv-qualifiers of M (if any), the new parameter is of type “rvalue reference to cv A” if the optional ref-qualifier of M is && or if M has no ref-qualifier and the first parameter of the other template has rvalue reference type. Otherwise, the new parameter is of type “lvalue reference to cv A”.
So, the original type for #2
is int operator*(T&, R&)
and its transformed type is int operator*(UniqueA&, UniqueB&)
, there's no doubt to the original type of #2
. However, I don't know what's the original type for #1
(member function template).
The structure of that rule seems that the emphasized part in the above rule should be considered as a step of producing the transformed template.
So, whether the original type of #1
is int operator*(B<T>&, R&)
or int operator*(R&)
. If it's the latter, that wouldn't consistent with common sense. Since int operator*(R&)
and int operator*(T&, R&)
do not match the number of parameters, how to compare them (A against P)?
How to read the rule for producing the transformed template correctly? If the emphasized part is not considered as a step of the transformation, instead it's a general rule for member function during the partial ordering, Does the rule make it misleading to place such a rule after the process of the transformation?
#1
during the partial ordering. "Two sets of types are used to determine the partial ordering. For each of the templates involved there is the original function type and the transformed function type." – xmh0511