cplusplus / CWG

Core Working Group
23 stars 7 forks source link

CWG2898 [over.best.ics.general] Clarify implicit conversion sequence from cv T to T #544

Open t3nsor opened 1 month ago

t3nsor commented 1 month ago

Full name of submitter: Brian Bi

Issue description: [over.best.ics.general]/7 says:

When the parameter has a class type and the argument expression has the same type, the implicit conversion sequence is an identity conversion. When the parameter has a class type and the argument expression has a derived class type, the implicit conversion sequence is a derived-to-base conversion from the derived class to the base class. A derived-to-base conversion has Conversion rank ([over.ics.scs]).

When the argument type is a cv-qualified class type, the following sentence in p6, and its example, appear to imply that the implicit conversion sequence is always the identity conversion:

Any difference in top-level cv-qualification is subsumed by the initialization itself and does not constitute a conversion.

The meaning of this sentence is unclear. If it applies only to the case where the argument type is the cv-qualified version of the parameter type, then we should say it much more clearly. If it applies to cv-qualified parameter types, then it's meaningless, because parameter types are never cv-qualified. If it applies also to other cases, it is probably wrong.

I believe the example reflects the intent. Clang and GCC agree.

Suggested resolution: Edit [over.best.ics.general]/6 and move its example to paragraph 7:

When the parameter type is not a reference, the implicit conversion sequence models a copy-initialization of the parameter from the argument expression. The implicit conversion sequence is the one required to convert the argument expression to a prvalue of the type of the parameter.
[Note 3: [...] — end note]
~Any difference in top-level cv-qualification is subsumed by the initialization itself and does not constitute a conversion.~
~[Example 2: A parameter of type A can be initialized from an argument of type const A. The implicit conversion sequence for that case is the identity sequence; it contains no “conversion” from const A to A. — end example]~

Edit [over.best.ics.general]/7 and add the example moved from p6, edited further as shown:

When ~the parameter has a class type and the argument expression has the same type~ the cv-unqualified version of the type of the argument expression is the same as the parameter type, the implicit conversion sequence is an identity conversion. When the parameter has a class type and the argument expression has a (possibly cv-qualified) derived class type, the implicit conversion sequence is a derived-to-base conversion from the derived class to the base class. A derived-to-base conversion has Conversion rank ([over.ics.scs]).
[Example 2: A parameter of type A can be initialized from an argument of type const A, even if overload resolution for copy-initialization of A from the argument would not find a viable function ([over.match.ctor], [over.match.viable]). The implicit conversion sequence for that case is the identity sequence; it contains no “conversion” from const A to A. — end example]

jensmaurer commented 1 month ago

"A parameter of type A can be initialized from an argument of type const A"

sounds like the eventual initialization would be possible; what we mean here is "an implicit conversion sequence can be formed", right?

jensmaurer commented 1 month ago

CWG2898

t3nsor commented 1 month ago

"A parameter of type A can be initialized from an argument of type const A"

sounds like the eventual initialization would be possible; what we mean here is "an implicit conversion sequence can be formed", right?

Good point. Yes, I suppose the text in the example should be amended accordingly.

jensmaurer commented 1 month ago

Updated.