Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The structure of the rule of producing a transformed template when partial ordering #4547

Open
xmh0511 opened this issue Mar 15, 2021 · 3 comments

Comments

@xmh0511
Copy link
Contributor

xmh0511 commented Mar 15, 2021

In order to determine which of the two function templates is more specialized, partial ordering is used to select the best candidate; This process needs a pair of type(The deduction process uses the transformed type as the argument template and the original type of the other template as the parameter template.)
The relevant rule is written in temp.func.order#3

  1. 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.
    Each function template M that is a member function is considered to have a new first parameter of type X(M), described below, inserted in its function parameter list. [...]

3.1 [...]
3.2 [...]

The first issue is:
This structure of the rule looks like adding an extra implicit object parameter to the function parameter list is a part of producing the transformed template. In other words, the original type of the member function does not have the implicit object parameter. That would make two candidates functions in which one is a member function template to be non-comparable? Because the transformed template of the non-member function does not have the same number of parameters as the original template of the member function template. Is it necessary to take the rule which describes that the parameter list of a member function template has an extra parameter out to make it to be an individual rule? And that rule will precede the rule of producing a transformed template.

The second issue is:

If exactly one of the function templates was considered by overload resolution via a rewritten candidate ([over.match.oper]) with a reversed order of parameters, then the order of the function parameters in its transformed template is reversed.

For this rule, Isn't the rule a bit misleading? Presumably, it says that the synthesized candidate is used to participate in the partial ordering. However, the synthesized candidate is in the overload set instead of the original function template which is rewritten by reversing the order of parameters. I mean the viable function template is not the original function template, so it does not be considered by overload resolution. Reversing the order of parameters of a synthesized function template does not make sense.

@xmh0511
Copy link
Contributor Author

xmh0511 commented Mar 16, 2021

@jensmaurer Could you please have a look?

@jensmaurer
Copy link
Member

For the first issue, I think the lookup rules prevent non-member functions and member functions from appearing in the same overload set. (If class member lookup found something, we don't go looking for non-member functions.)

The second issue does not feel editorial to me.

@xmh0511
Copy link
Contributor Author

xmh0511 commented Apr 3, 2021

For the first issue, I think the lookup rules prevent non-member functions and member functions from appearing in the same overload set. (If class member lookup found something, we don't go looking for non-member functions.)

Why would be that? The example that follows [temp.func.order#3] exactly indicates the case where the overload set may comprise non-member functions and member functions.

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

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

The invocation at #3 will make the overload set comprise the specializations of the templates that are defined at #1 and #2. According to the current structure of [temp.func.order#3], It sounds like the transform template for #1 is template<class R> int operator*(B<T>&, R&); while the original template for #2 is still template<class T, class R> int operator*(T&, R&);; However, the transform template for #2 is template<class T, class R> int operator*(T&, R&); but the original template for #1 looks like it is template<class R> int operator*(R&); . My reason is, the following rule

Each function template M that is a member function is considered to have a new first parameter of type X(M)

Appears after the introduction sentence

To produce the transformed template...

The above issue has discussed at https://stackoverflow.com/a/65206517/11796722

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants