Date: Wed, 20 Nov 2024 14:24:02 +0100
There is probably a lack in the current [dcl.spec.auto.general] (§9.2.9.7.1)
I use the text from https://eel.is/c++draft/#dcl.dcl (generated on 9th of
Nov, 2024).
Parts p3 and p4 read:
p3: A placeholder type can appear in the *decl-specifier-seq*
<https://eel.is/c++draft/dcl.spec.general#nt:decl-specifier-seq> for a function
declarator that includes a *trailing-return-type*
<https://eel.is/c++draft/dcl.decl.general#nt:trailing-return-type> ([dcl.
fct] <https://eel.is/c++draft/dcl.fct>).
<https://eel.is/c++draft/dcl.spec.auto#general-3.sentence-1>
p4: A placeholder type can appear in the *decl-specifier-seq*
<https://eel.is/c++draft/dcl.spec.general#nt:decl-specifier-seq> or
*type-specifier-seq*
<https://eel.is/c++draft/dcl.type.general#nt:type-specifier-seq> in the
declared return type of a function declarator that declares a function; the
return type of the function is deduced from non-discarded return statements,
if any, in the body of the function ([stmt.if]
<https://eel.is/c++draft/stmt.if>).
<https://eel.is/c++draft/dcl.spec.auto#general-4.sentence-1>
This is not much different compared to the original text I studied from
draft n4849 (last before official C++20), where [decl.spec.auto]-p3 reads:
"
The placeholder type can appear with a function declarator in the
decl-specifier-seq, type-specifier-seq, conversion-function-id, or
trailing-return-type, in any context where such a declarator is valid. If
the function declarator includes a trailing-return-type ([dcl.fct]), that
trailing-return-type specifies the declared return type of the function.
Otherwise, the function declarator shall declare a function. If the
declared return type of the function contains a placeholder type, the
return type of the function is deduced from non-discarded return
statements, if any, in the body of the function ([stmt.if]).
"
The intent appears to force function declarators to declare a function in
case a placeholder is used for returning type, otherwise it is not possible
to deduce in case of definitions of function types, function pointer types,
or function pointers.
However, it should be mentioned that if the trailing-return-type itself
contains a placeholder type, then we should fall back to the constraint
that a function has to be declared.
I see this lack in both the text of draft n4849 and the current draft text.
e.g.
auto (*p)() -> auto; // ill-formed (as all major compilers act)
A possible solution is modifying p3 as follows:
A placeholder type can appear in the *decl-specifier-seq*
<https://eel.is/c++draft/dcl.spec.general#nt:decl-specifier-seq> for a function
declarator that includes a *trailing-return-type*
<https://eel.is/c++draft/dcl.decl.general#nt:trailing-return-type> ([dcl.
fct] <https://eel.is/c++draft/dcl.fct>) that does not contain, in turn,
another placeholder type.
<https://eel.is/c++draft/dcl.spec.auto#general-3.sentence-1>
On the other hand, current p1 recalls the fact that the
trailing-return-type, if present, is the one that effectively replaces the
declared returnd type, therefore the context cannot implicitly be without a
placeholder for the trailing type.
As second point, I appreciate some redundancy was removed (compared to
draft n4849), for example the fact that type-specifier-seq already includes
the case of conversion-function-id.
However, current p1 is likely too specialized when it reads "... or as one
of the *type-specifier*
<https://eel.is/c++draft/dcl.type.general#nt:type-specifier>*s* in a
*trailing-return-type*
<https://eel.is/c++draft/dcl.decl.general#nt:trailing-return-type> ...", as
I guess this excludes the case of conversion function id,
unless I am wrong supposing that conversion function ids do not fall in the
case of "... as one of the *decl-specifier*
<https://eel.is/c++draft/dcl.spec.general#nt:decl-specifier>*s* in the
*decl-specifier-seq*
<https://eel.is/c++draft/dcl.spec.general#nt:decl-specifier-seq> ...".
Of coruse, conversion functions are still allowed to be auto()
[class.conv.ftc] (§14.8.3-p3 & p8).
Last detail: In [class.conv.fct]-p3 there is "trailing return type" in
commented code without dashes. In my pdf version of n4849, it is the only
occurrence, as all others both in text and commented code for the examples,
appear with dashes.
I use the text from https://eel.is/c++draft/#dcl.dcl (generated on 9th of
Nov, 2024).
Parts p3 and p4 read:
p3: A placeholder type can appear in the *decl-specifier-seq*
<https://eel.is/c++draft/dcl.spec.general#nt:decl-specifier-seq> for a function
declarator that includes a *trailing-return-type*
<https://eel.is/c++draft/dcl.decl.general#nt:trailing-return-type> ([dcl.
fct] <https://eel.is/c++draft/dcl.fct>).
<https://eel.is/c++draft/dcl.spec.auto#general-3.sentence-1>
p4: A placeholder type can appear in the *decl-specifier-seq*
<https://eel.is/c++draft/dcl.spec.general#nt:decl-specifier-seq> or
*type-specifier-seq*
<https://eel.is/c++draft/dcl.type.general#nt:type-specifier-seq> in the
declared return type of a function declarator that declares a function; the
return type of the function is deduced from non-discarded return statements,
if any, in the body of the function ([stmt.if]
<https://eel.is/c++draft/stmt.if>).
<https://eel.is/c++draft/dcl.spec.auto#general-4.sentence-1>
This is not much different compared to the original text I studied from
draft n4849 (last before official C++20), where [decl.spec.auto]-p3 reads:
"
The placeholder type can appear with a function declarator in the
decl-specifier-seq, type-specifier-seq, conversion-function-id, or
trailing-return-type, in any context where such a declarator is valid. If
the function declarator includes a trailing-return-type ([dcl.fct]), that
trailing-return-type specifies the declared return type of the function.
Otherwise, the function declarator shall declare a function. If the
declared return type of the function contains a placeholder type, the
return type of the function is deduced from non-discarded return
statements, if any, in the body of the function ([stmt.if]).
"
The intent appears to force function declarators to declare a function in
case a placeholder is used for returning type, otherwise it is not possible
to deduce in case of definitions of function types, function pointer types,
or function pointers.
However, it should be mentioned that if the trailing-return-type itself
contains a placeholder type, then we should fall back to the constraint
that a function has to be declared.
I see this lack in both the text of draft n4849 and the current draft text.
e.g.
auto (*p)() -> auto; // ill-formed (as all major compilers act)
A possible solution is modifying p3 as follows:
A placeholder type can appear in the *decl-specifier-seq*
<https://eel.is/c++draft/dcl.spec.general#nt:decl-specifier-seq> for a function
declarator that includes a *trailing-return-type*
<https://eel.is/c++draft/dcl.decl.general#nt:trailing-return-type> ([dcl.
fct] <https://eel.is/c++draft/dcl.fct>) that does not contain, in turn,
another placeholder type.
<https://eel.is/c++draft/dcl.spec.auto#general-3.sentence-1>
On the other hand, current p1 recalls the fact that the
trailing-return-type, if present, is the one that effectively replaces the
declared returnd type, therefore the context cannot implicitly be without a
placeholder for the trailing type.
As second point, I appreciate some redundancy was removed (compared to
draft n4849), for example the fact that type-specifier-seq already includes
the case of conversion-function-id.
However, current p1 is likely too specialized when it reads "... or as one
of the *type-specifier*
<https://eel.is/c++draft/dcl.type.general#nt:type-specifier>*s* in a
*trailing-return-type*
<https://eel.is/c++draft/dcl.decl.general#nt:trailing-return-type> ...", as
I guess this excludes the case of conversion function id,
unless I am wrong supposing that conversion function ids do not fall in the
case of "... as one of the *decl-specifier*
<https://eel.is/c++draft/dcl.spec.general#nt:decl-specifier>*s* in the
*decl-specifier-seq*
<https://eel.is/c++draft/dcl.spec.general#nt:decl-specifier-seq> ...".
Of coruse, conversion functions are still allowed to be auto()
[class.conv.ftc] (§14.8.3-p3 & p8).
Last detail: In [class.conv.fct]-p3 there is "trailing return type" in
commented code without dashes. In my pdf version of n4849, it is the only
occurrence, as all others both in text and commented code for the examples,
appear with dashes.
Received on 2024-11-20 13:24:15