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 permissible types in [over.match.conv] should not be reference types #4761

Open
xmh0511 opened this issue Jul 19, 2021 · 7 comments
Open

Comments

@xmh0511
Copy link
Contributor

xmh0511 commented Jul 19, 2021

Assuming that “cv T” is the type of the object being initialized, the candidate functions are selected as follows:

  • The permissible types for non-explicit conversion functions are those that can be converted to type T via a standard conversion sequence ([over.ics.scs]).
  • For direct-initialization, the permissible types for explicit conversion functions are those that can be converted to type T with a (possibly trivial) qualification conversion ([conv.qual]); otherwise there are none.

Is that reference to type T considered the permissible type here? It's probably not, if it were, it will be conflicted with [over.match.funcs#general-7]. From the perspective of conversion sequence, an argument of reference type should be first adjusted to the referenced type(T) as per [expr#type-1] prior to any further analysis. Hence, it is arguably said that from T to T satisfies the above requirement. It's unclear here, maybe we should explicitly say that

The permissible types for non-explicit conversion functions are those non-reference types that can be converted to type T via a standard conversion sequence ([over.ics.scs]).

For direct-initialization, the permissible types for explicit conversion functions are those non-reference types that can be converted to type T with a (possibly trivial) qualification conversion ([conv.qual]); otherwise there are none.

It seems that the wording possibly trivial is newly introduced, Is that if we say identity conversion is more clear?

@xmh0511 xmh0511 changed the title The permissible types in [over.match.conv] should not be reference type The permissible types in [over.match.conv] should not be a reference type Jul 19, 2021
@xmh0511 xmh0511 changed the title The permissible types in [over.match.conv] should not be a reference type The permissible types in [over.match.conv] should not be reference types Jul 19, 2021
@jensmaurer
Copy link
Member

I think the phrasing "convert a type to another type" has a deeper problem.
In [conv.general] p1, we say "A standard conversion sequence will be applied to an expression if necessary to convert it to a required destination type."

So, a standard conversion sequence converts an expression to a type. Attempting to convert a type to a type is ill-defined.

@jensmaurer
Copy link
Member

@opensdh
Copy link
Contributor

opensdh commented Aug 24, 2021

Since we're talking about conversion functions here, one approach is to just say that the expression being converted is a call to the conversion function (so that [expr.call]/14, the "inverse" of decltype, applies). That said, standard conversion sequences don't care much about the value category of the source expression (since the lvalue-to-rvalue conversion always applies when initializing an object), so I bet we can simply say "those object types of which a prvalue can be converted" (and let [over.match.funcs.general]/7 cover the rest, as stated above).

As for "possibly trivial", [conv.qual]/3 doesn't actually require that T1 and T2 differ, but I wanted to be clear about that case since it's not used in forming standard conversion sequences.

@xmh0511
Copy link
Contributor Author

xmh0511 commented Aug 24, 2021

I think, from T1 to T2 is just an identity conversion if T1 and T2 are the same. If we say they are the "possibly trivial" qualification conversion, it will result in this problem https://stackoverflow.com/questions/65282778/is-an-identity-conversion-of-pointer-type-be-considered-as-qualification-convers, which means it will influence the rank in overload resolution. Hence, I hope we could distinguish them to be two different kinds of conversion.

@opensdh
Copy link
Contributor

opensdh commented Aug 24, 2021

it will result in this problem

It won't: as discussed there, the sequence formation process doesn't use the vacuous qualification conversion because it doesn't need to do so. Here, we explicitly ask whether it's possible to do so, and for the same type it is. If we think it's clearer to exclude that case in [conv.qual] and then say "T and those that can…", we can certainly do so.

Incidentally, the [over.ics.rank]/3.2.5 cited there also discusses converting a type to a type (albeit via a specific kind of conversion).

@xmh0511
Copy link
Contributor Author

xmh0511 commented Aug 25, 2021

If we merely according to the definition of the qualification conversion, convert int* to int* itself could be considered as a qualification conversion since it didn't conflict with the definition. However, in some special cases, such as the overload resolution, the qualification conversion is explicitly considered to have the exact match rank as per [over.ics.scs]. But, identity conversion has a higher priority than any other conversion sequence with the same rank(i.e. exact match) as per [over.ics.rank#3.2.1]. I'd prefer to consider the conversion sequence that requires no conversion to be an identity conversion rather than a "trivial" qualification conversion(int* => int*). And we should use this concept anywhere in the standard to make the meaning be consistent.


It seems not only [over.ics.rank]/3.2.5 but also somewhere in the standard use that possibly wrong utterance.

@xmh0511
Copy link
Contributor Author

xmh0511 commented Sep 1, 2021

so I bet we can simply say "those object types of which a prvalue can be converted" (and let [over.match.funcs.general]/7 cover the rest, as stated above).

This should also apply to [over.match.ref]

For direct-initialization, the permissible types for explicit conversion functions are the members of R where T2 can be converted to type T with a (possibly trivial) qualification conversion ([conv.qual]); otherwise there are none.

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

3 participants