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

[dcl.spec.auto.general] Call to conversion function whose conversion-function-id contains a placeholder CWG2493 #4811

Open
xmh0511 opened this issue Aug 13, 2021 · 9 comments
Labels
cwg Issue must be reviewed by CWG. not-editorial Issue is not deemed editorial; the editorial issue is kept open for tracking.

Comments

@xmh0511
Copy link
Contributor

xmh0511 commented Aug 13, 2021

struct A{
  operator auto(){
     return 0;
  }
};
int main(){
   A a;
   a.operator auto(); // #1
   a.operator int(); //  #2
}

In this example, GCC only accepts the manner of #2 while Clang only accepts #1. However, The usage of #1 seems to be ill-formed as per [dcl.spec.auto#6]. For operator int, it's not the id-expression of the conversion function whose name should have been operator auto.

As per [dcl.spec.auto#13], that is:

Redeclarations or specializations of a function or function template with a declared return type that uses a placeholder type shall also use that placeholder, not a deduced type.

So, it seems that operator auto might be the unique name to nominate the conversion function(As a qualified-id that appears in the declarator-id when defining the entity outside the enclosing class definition).

So, the issue falls out which is the name of the conversion function? Literally, the unique name should be operator auto, however, when using the name as an id-expression of a class member access expression, such usage is forbidden by [dcl.spec.auto]. The standard does not specify what should do here.

@xmh0511
Copy link
Contributor Author

xmh0511 commented Aug 13, 2021

Issue #4671 is potentially related to this. I think we could consider auto to be a template parameter that participates in template argument deduction in the manner as [dcl.type.auto.deduct] did. And we are just necessary to give a normative rule to specify how to refer to that specialization.

@jensmaurer jensmaurer added cwg Issue must be reviewed by CWG. not-editorial Issue is not deemed editorial; the editorial issue is kept open for tracking. labels Aug 13, 2021
@jensmaurer
Copy link
Member

jensmaurer commented Aug 13, 2021

The (return) type of "operator auto" is deduced from its definition.

#1 is obviously wrong, but we lack wording that describes how "auto" gets transformed to "int" so that #2 is valid. CWG needs to discuss this.

@jensmaurer jensmaurer changed the title explicitly call of a conversion function whose conversion-function-id contains a placeholder specifier CWG2493 [dcl.spec.auto.general] Call to conversion function whose conversion-function-id contains a placeholder CWG2493 Aug 13, 2021
@xmh0511
Copy link
Contributor Author

xmh0511 commented Aug 13, 2021

However, "operator auto" should be the declarator-id on grammar, which means the name lookup rule has to use the declarator-id to find out the declaration. Maybe, the rule for "how auto gets transformed to int" would cover this concern.

@zygoloid
Copy link
Member

#1 is obviously wrong

I don't think that's obvious. See prior discussion in http://lists.isocpp.org/core/2018/01/3737.php, which seemed to be leaning towards #1 being correct.

@jensmaurer
Copy link
Member

That discussion predates P1787R6, I believe.

@xmh0511
Copy link
Contributor Author

xmh0511 commented Aug 16, 2021

[dcl.spec.auto.general] p6 says

A program that uses a placeholder type in a context not explicitly allowed in [dcl.spec.auto] is ill-formed.

The use of auto in an id-expression in the class member access expression is not explicitly allowed in [dcl.spec.auto]. Hence, it can arguably say it's wrong.

@zygoloid
Copy link
Member

I don't think P1787R6 really intended to address this question. To the extent it did anything here, I think it made the problem worse -- after that wording change, I think we no longer consider a function whose name is operator auto when looking for a conversion to int at all (the new [over.match.funcs]p7 looks for a function named operator int, whereas the old wording looked instead at the return types of the conversion functions) -- so I think this corner case was not considered as part of that wording change at all.

@opensdh
Copy link
Contributor

opensdh commented Apr 6, 2022

The interpretation that I want, consistent with the (unfortunate) fact that operator auto is a deduced return type rather than a conversion function template, is that the function's name, formed as it is from its return type, is operator int. The unadorned alternative doesn't seem reasonable:

struct X {
  virtual operator int() {return 1;}
};
struct Y {
  operator auto() {return 1;}
};
int f(X x) {return x.operator int();}  // OK
int f(Y y) {return y.operator int();}  // error: name lookup failed
struct Y2 : X {
  operator auto() override {return 1;}  // error: doesn't override
};

This was, I believe, at least my subconscious intent in writing P1787.

Since we can't refer to a function with an undeduced return type, this almost works even for a function that has been declared but not defined:

struct Z {
  operator auto();
};
void f(Z z) {
  z.operator auto();  // error: name lookup failed
  z.operator int();   // error: maybe you guessed its name right, but you can't call it here
}

However, it breaks down if we try to do more than that:

struct W {
  operator auto();
  operator auto();  // ???
};

Of course, neither does it really work to just say that operator auto is the name:

struct V {
  operator auto();
  operator auto*();  // OK...
  static int i;
};
V::operator auto() {return &i;}
V::operator auto*() {return &i;}
int *p=V();  // what does this call?

If we do say that operator auto is the name, perhaps what we need is a special-purpose lookup rule "If you look for operator T, you also find any function whose name is operator auto whose return type is T.", although there would still be the question of what to do if the return type is not (yet) known. We could also make lookup for operator auto never find anything: being able to call y.operator auto() seems to have even less expected value than is usual for calling conversion functions by name.

@jensmaurer
Copy link
Member

jensmaurer commented Apr 6, 2022

@opensdh, I'm wondering whether that discussion should be on the CWG e-mail reflector, with reference to CWG2493 and CWG1670, rather than on an editorial issue, which this topic definitely isn't.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cwg Issue must be reviewed by CWG. not-editorial Issue is not deemed editorial; the editorial issue is kept open for tracking.
Projects
None yet
Development

No branches or pull requests

4 participants