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

[over.best.ics] Wording might be confusing #2288

Closed
cpplearner opened this issue Aug 4, 2018 · 8 comments
Closed

[over.best.ics] Wording might be confusing #2288

cpplearner opened this issue Aug 4, 2018 · 8 comments
Assignees

Comments

@cpplearner
Copy link
Contributor

[over.best.ics]/10:

If several different sequences of conversions exist that each convert the argument to the parameter type, the implicit conversion sequence associated with the parameter is defined to be the unique conversion sequence designated the ambiguous conversion sequence.

It might be helpful to clarify the meaning of "several different sequences of conversions". E.g. int -> int is not an ambiguous conversion sequence even though int -> float -> int and int -> long -> int are both "sequences of conversions" in plain-English sense.

@jensmaurer
Copy link
Member

jensmaurer commented Aug 11, 2018

Do you have a code example highlighting your concern? The paragraph simply says if there are several possible conversions, the conversion sequence for this parameter will be ignored when finding the best viable function.

@cpplearner
Copy link
Contributor Author

cpplearner commented Aug 12, 2018

Though I don't think people can be confused in the int -> int case, it's easy to be trapped in the following case:

struct X {
    operator char();
    operator long();
};

int f(int); // #1
int x = f(X{});

One may think that there are two possible sequences of conversions: X -> char -> int and X -> long -> int, and thus [over.best.ics]/10 makes X -> int an ambiguous conversion sequence and (since #1 is the best and only viable function) the call f(X{}) is ill-formed.

I think the intention is clear: The implicit conversion sequence models a copy-initialization ([over.best.ics]/6). The copy initialization from X{} to int is unambiguous. Therefore the conversion sequence is not ambiguous.

@jensmaurer
Copy link
Member

Ok. It seems [over.best.ics] p10 should say that we take the best conversion sequence for each parameter (which might be ambiguous) before we're comparing entire functions. Changing this would modify the semantics of the normative text, although it's very obvious what the intent is.

@zygoloid, do you feel this is editorial?

@cpplearner
Copy link
Contributor Author

The semantics of the normative text might already match the intent, given [over.best.ics]/1:

The sequence of conversions [...] is governed by the rules for initialization of an object or reference by a single expression ([dcl.init], [dcl.init.ref]).

and [dcl.init]/(17.7):

The applicable conversion functions are enumerated ([over.match.conv]), and the best one is chosen through overload resolution ([over.match]).

But that needs to be made more obvious.

@jensmaurer
Copy link
Member

@cpplearner: One of the tricky issues is that "initialization of an object by a single expression" isn't the full truth. For example, access control does not affect formation of an implicit conversion sequence, but could make the initialization ill-formed. So, I'm hesitant to put too much weight into the "initialization" wording here. (It would also be nice if the wording said something like "copy-initialization" instead of just "initialization".)

@jensmaurer jensmaurer added the decision-required A decision of the editorial group (or the Project Editor) is required. label Oct 10, 2018
@jensmaurer
Copy link
Member

Editorial meeting: "If there are multiple well-formed implicit conversion sequences converting the argument to the parameter type, ..."

@jensmaurer jensmaurer removed the decision-required A decision of the editorial group (or the Project Editor) is required. label Nov 6, 2018
@jensmaurer jensmaurer self-assigned this Nov 27, 2018
@RealLitb
Copy link

I think this is factually incorrect and would kindly request reviewing this, because the cases in question do not have multiple implicit conversion sequences to consider, but multiple user defined conversion candidate functions within a single user defined conversion sequence that's in the process of being formed. That's vastly different: Merely a converting constructor a conversion function are just user defined conversions, and such a thing wrapped by two standard conversion sequences will make it a user defined conversion sequence - an implicit conversion sequence.

The text used to say "different sequences of conversions" because overload resolution in the cases of interest for the user defined conversion will be ambiguous, and it is impossible to construct a user defined conversion sequence from an ambiguity (in fact, previous editions of the Standard used to say in the preceeding paragraph that in such a scenario no implicit conversion sequence can be formed, and I suspect this next paragraph was intended as an exception to that rule). What you have when this paragraph applies is merely several candidates of { standard conversion sequence, a user defined conversion call, and another standard conversion sequence }, in a nested overload resolution for the user defined conversion function/ctor. But you haven't selected one of these sequences of conversions to be your user-defined conversion sequence yet, and you can't because they're ambiguous.

Also I do not believe that the change to "multiple well-formed implicit conversion sequences - besides introducing this difficulty - clarifies the clarity issue raised by cpplearner". Perhaps a direct reference to the ambiguity situation would be better suited here (but requires non-editorial discussion, I suspect).

@bogiord
Copy link

bogiord commented Jul 25, 2019

I agree with @RealLitb that the previous wording was definitely... less bad, but still didn't reflect the fact that there are many cases where multiple conversions exist but overload resolution can choose a best one, and that obviously doesn't result in an ambiguous conversion sequence.

Suggestion:

If the sequence of conversions required to convert an argument to a parameter type is ambiguous, the implicit conversion sequence associated with...

I think this logically complements the previous paragraph, and is consistent with the wording in the previous two paragraphs and in [dcl.init]/17.6.3, 17.7.

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

4 participants