Skip to content

[over.match.funcs] Conversion function template candidates #699

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

Open
randomnetcat opened this issue Apr 14, 2025 · 3 comments
Open

[over.match.funcs] Conversion function template candidates #699

randomnetcat opened this issue Apr 14, 2025 · 3 comments

Comments

@randomnetcat
Copy link

randomnetcat commented Apr 14, 2025

Full name of submitter: Janet Cobb

Reference (section label): [over.match.funcs]

Issue description:

Consider the following code:

struct S {
    template<int = 0>
    operator int&&() { throw 0; }
};

int i = S();

The four common compilers agree that this is well-formed.

Initialization is done pursuant to [dcl.init.general]/16.7. As far as I can tell, the only candidates are those defined by [over.match.funcs.general]/7. Since the object being initialized is of type int, the first sentence only introduces candidates that would be found by operator int, which does not include the conversion function template. The remainder of the paragraph explicitly excludes conversion function templates (regardless of the "permissible types"). Thus, there do not appear to be any candidates for the conversion.

Since all common implementations think operator int&& is a candidate, I'm filing this defect report rather than a bug report with each implementation, in the hopes that this is an issue with the wording.

Here are some other interesting cases with templates that do not appear to be candidates under the current wording:

Suggested resolution:

Exactly how this should be resolved is unclear. One possibility would be to modify the first sentence of [over.match.funcs.general]/7 to include cv T, cv T&, and cv T&& just like the second portion of the paragraph does. This would address the initial example, but not any of the other cases that implementations think are well-formed.

This suggests that a potential resolution would be to explicitly include types U that can be converted to T by some specific subset of conversions (similarly to, e.g., [over.match.conv]. Another possible resolution is that the status quo is correct and that all of the implementations are wrong, although implementing that seems likely to break code and perhaps counterintuitive (since, to me at least, it seems like the original example should be well-formed).

@t3nsor
Copy link

t3nsor commented Apr 21, 2025

Now that I'm looking at this again, I think the normative text is fine. [temp.deduct.conv] explains that if we get here from [over.match.funcs], then the rules in the remainder of [temp.deduct.conv] apply, which allow certain inexact matches. The behavior of the implementations appears to be consistent with these rules, except in the known/unknown bound case, where we obviously don't want to support it, and the implementations that accept should just be fixed.

I think [over.match.funcs.general]/7 needs a note that explains that the result of the search in this case can include inexact matches pursuant to [temp.deduct.conv], and an example as well.

@randomnetcat
Copy link
Author

randomnetcat commented Apr 21, 2025

Ah, I see: I have completely missed [class.member.lookup]/7, so the conversion function templates are candidates, which is so counterintuitive that I would have never thought to look for it. Yes, I agree this is fine, then. Sorry for the trouble.

@t3nsor
Copy link

t3nsor commented Apr 21, 2025

Considering that multiple language lawyers were confused by this when it was discussed elsewhere, I think that a note and example are still called for.

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

2 participants