cplusplus / CWG

Core Working Group
23 stars 7 forks source link

[dcl.type.auto.deduct] The deduction for the return statement that has no operand is ill-formed #552

Open xmh0511 opened 3 weeks ago

xmh0511 commented 3 weeks ago

Full name of submitter (unless configured in github; will be published with the issue): Jim X

Consider this case:

auto fun(){
    return;
}

[dcl.type.auto.deduct] p2.1.1 says:

If the return statement has no operand, then E is void().

[dcl.type.auto.deduct] p3 says:

Deduce a value for U using the rules of template argument deduction from a function call, where P is a function template parameter type and the corresponding argument is E. If the deduction fails, the declaration is ill-formed.

[temp.deduct.general] p8 says:

If a substitution results in an invalid type or expression, type deduction fails.

[dcl.fct] p3 says;

Except for this special case, a parameter shall not have type cv void.

violate [dcl.fct] p3 would case the program is ill-formed. So, the deduction for void() with template parameter type U is void, substitutes this type would result in an invalid function type, hence [dcl.type.auto.deduct] p3 says the declaration is ill-formed. However, this is a legal use.

jensmaurer commented 2 weeks ago

[dcl.fct] p3 (as quoted) says "Except for this special case, a parameter shall not have type cv void."

That is not a statement on the return type. The example you gave has no parameters.

t3nsor commented 2 weeks ago

I think the part that @xmh0511 takes issue with is this, from [dcl.type.auto.deduct]/3:

[...] Obtain P from T by replacing the occurrences of type-constraintopt auto either with a new invented type template parameter U or, if the initialization is copy-list-initialization, with std​::​initializer_list. Deduce a value for U using the rules of template argument deduction from a function call, where P is a function template parameter type and the corresponding argument is E. [...]

If P is a function template parameter type, then it has a corresponding invented function template. And if P is U where U is a template parameter, can deduction succeed when the corresponding argument in the call is void()? [temp.deduct.general]/11.10 seems to say no.

We seemingly want to use all the rules from [temp.deduct.general] that actually tell us how to find U, but without actually imposing the substitution specified by [temp.deduct.general]/5.