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
[class.virtual] Overriding virtual function through an explicit object member function CWG2554 #5144
Comments
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p0847r7.html clearly says this about the intent:
So, it was originally intended that old-style and new-style member functions don't override each other. It seems to me the problem is that explicit-object member functions with a by-value parameter correspond to an implicit-object member function (which has a by-reference parameter). This may have calling convention impact, so is probably not desired. Example:
I think this should not be a redeclaration. |
I think my I think we need a narrow fix for [class.virtual] that says that a virtual member function shall not be an explicit-object member function (or that only same-kind functions override). Or something like that. |
We say they cannot be declared virtual here: http://eel.is/c++draft/dcl.dcl#dcl.fct-6 |
@brevzin Derived::show isn't declared virtual since the declaration contains no |
@brevzin , unforunately, that's not quite sufficient, because "declared I think we need "An explicit object member function shall not be virtual." in [class.virtual], then we can drop the "virtual" keyword prohibition in [dcl.fct] p6 and possibly replace it with a note. |
@jensmaurer Hmmm, I would argue that |
Tangent: "corresponds" is not the right criterion to define "override": http://lists.isocpp.org/core/2021/12/11840.php |
What is the purpose of "ignoring object parameters" in the proposed suggestion? Does it intend to say that just skip [basic.scope.scope] p3 when we check whether such two non-static member functions correspond where there is at least one explicit object member function? However, even if we ignore the object parameters(i.e. the implicit and explicit object parameters), they still are non-static member functions, which means
this rule still can work. If the wording means this intent, Is it better to say
|
Yes, and we ignore any non-corrrespondence in object parameters, so "if both are non-static members, they have corresponding object parameters" is essentially void. I agree it would be better to phrase the rule in a more constructive rather than "do this, except X" way. |
Totally agree. Unlike ignoring trailing requires-clauses, that can mean we ignore any difference from trailing requires-clauses when considering whether two declarations correspond. The special here is even though we ignore object parameters, it cannot change the reality that they are non-static member functions. This will make "if both are non-static members, they have corresponding object parameters" hard to interpret when we consider it. |
@jensmaurer A friendly reminder, CWG2554 seems to admit that these functions are all overriding in the following cases: struct B3 {
virtual void f();
};
struct D3 : B3 {
void f(this D3&); // ok, does not override B3::f
}; This case is sourced from http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p0847r7.html, the comment might be wrong since Another case struct A{
virtual void show();
};
struct U{};
struct B{
operator U();
void show(this U){}
}; Again, |
Yes, discussion around CWG2554 has progressed beyond the intent originally expressed in P0847R7, including making more derivation examples ill-formed. |
Ok. That means
|
Yes, D3 and B override their base class functions and, with CWG2553, make the program ill-formed. |
Thanks. Please consider the above suggestion for CWG2554. |
Consider this example
According to [basic.scope.scope] p1,
#1
corresponds to#2
as per [basic.scope.scope] p4 if their object parameters should be corresponding. [basic.scope.scope] p3 says thatIn this case,
#1
and#2
satisfy the first bullet since the type of the implicit object parameter of#1
isBase&
while the type of the explicit object parameter of#2
isBase
, they have the same type after removing the top-level references. Hence,#2
can override#1
? Is it the intention after introducing deducing this?If an explicit object member function can override an implicit object member function, it seems that the class type of the explicit object parameter must be the base class. Is it also the artificial intent?
The text was updated successfully, but these errors were encountered: