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
[over.match.funcs.general] p5 user-defined conversions sequence are not considered for object parameter CWG2557 #5364
Comments
I think the example has nothing to do with user-defined conversions or functions. We'd also expect an ill-formed error if Thus, the right place to look for a restriction is [expr.ref]. |
@opensdh, I'm not seeing anything that would make this example ill-formed. I think [expr.ref] should contain a check before the if-ladder on the kind of E2. |
Yes, that could be a more general way instead of concerning only member functions. If we would have that restriction, is it necessary to remain the sentence(user-defined conversion...) in [over.match.funcs.general] p5? |
Yes, I think that's still necessary for cases roughly similar to this:
|
However, [over.match.oper] p2 will reinterpret the expression to a function call, which depends on what kind of the function is. For non-member function, it is |
There is also another concern: Are user-defined conversion sequences permitted for an explicit object parameter? This is even not mentioned by [over.match.funcs.general] p5 that only talks about implicit object parameter. |
I think the restriction for the non-static case has been mentioned a couple of times in other issues, it is https://eel.is/c++draft/expr.prim.id.general#3 For the static members case, I'd say it is implementations' bug. It would be natural to extrapolate CWG315 decision from «we don't care about the result of the object expression» to «also, we don't care about its type» if the RHS of [expr.ref] names a static member. |
Plus there is https://eel.is/c++draft/class.access.base#6 |
@languagelawyer [expr.prim.id.general] p3 and [class.access.base] p6 are well applied to non-static member. I wanted to use the code at |
@jensmaurer If "user-defined conversion sequence restriction" is necessary for implicit object parameter, could we place it in [over.best.ics] and replace it with constructive wording? BTW, how about the explicit object parameter? |
I think the explicit object parameter wants all conversions it can get; please double-check the paper that introduced it. Regarding the move to [over.best.ics]: Yes, we probably could do that. I'm not seeing that high on the priority list, given that it works as currently specified (even though it's not pretty). |
Before P1787R6 it did contain
but that doesn't work anymore because of |
I don't see how changing "shall name a member" to "shall denote a member" allows enum E {e};
struct X {
using E::e;
};
int f(X x) {return x.e;} because |
Thanks for the more complete example. I thought you were concerned about the qualified-id in |
Maybe "If E2 is a qualified-id, the terminal name of its nested-name-specifier shall denote the type of E1 or a base class thereof." |
I think that rule makes sense: if you want to refer to |
Amended CWG2557 accordingly. |
Can we strike the insufficient text from [expr.prim.id.general]/3 now? I don't see how an unqualified-id would ever refer to the wrong class. |
Good point: CWG2557 is updated. |
enum E {e};
struct X {
using E::e;
};
int f(X x) {return x.e;} For this example, only [expr.ref] p6.5 mentions enumerator in a class member access. It says: If E2 is a member enumerator, Is
So, how does [expr.ref] specify that
Since [basic.lookup.general] p3 says
I also think this example is better than the example in #4731 to expose the subject of that issue. |
It seems we should fix that as a drive-by, plus add the example. CWG2557 is updated. |
@jensmaurer @opensdh struct A{
enum class C{
a = 0
};
};
int main(){
A a;
auto c = a.C::a; //#1
} For this, I posted the bug file for GCC. However, consider a subtle case struct A{
enum C{ // unscoped enumeration results in that `a` is a member of class `A`
a = 0
};
};
int main(){
A a;
auto c = a.C::a; //#1
} Is this well-formed or ill-formed, according to the wording in CWG2557, it is ill-formed since |
[over.match.funcs.general] p5 says
It sounds like a note. The implicit conversion sequence only considered whether converting an argument to the type of the parameter can form an implicit conversion sequence. So, "retains its identity" is not matter with the reason why user-defined conversions cannot be applied. Consider this example:
Even though [class.mfct.non.static] p2 says
However, it restricts nothing on the conversion sequence that converts the implicit object argument to the type of the object parameter.
It is even worse the status quo is not clear for a static member function. [over.match.funcs.general] p4 says
which bullet can interpret why
#2
is ill-formed? neither [basic.lookup], [expr.ref], nor [over.match.funcs.general]I think we should have a formal rule in a similar manner as [over.best.ics.general] p4, in that subclause, it is a reasonable place to talk about conversion sequence.
Such as
[over.match.funcs.general] p5 can refer to the added rule. In addition, the original [over.match.funcs.general] p5 does not cover explicit object parameter, does it mean user-defined conversion sequence can be considered for it?
For the static member case at
#2
, I haven't found a corresponding rule that can interpret the ill-formed.The text was updated successfully, but these errors were encountered: