According to 7.1.5 [dcl.constexpr] paragraph 3, no declarations are permitted in the body of a constexpr function. This seems overly restrictive. At least three kinds of declarations would seem to be helpful in writing such functions: static_assert, typedef and alias declarations, and local automatic variables initialized with constant expressions. (Similar considerations apply to lambdas in which the lambda-return-type-clause is omitted.)
The body of a constexpr function is required by 7.1.5 [dcl.constexpr] paragraph 3 to be of the form
However, there does not seem to be any good reason for prohibiting the alternate return syntax involving a braced-init-list. The restriction should be removed.
A return statement without an expression with neither an expression nor a braced-init-list can be used only in functions that do not return a value...7.1.5/3:
7.1.5/4:its function-body shall be a compound-statement of the formthat contains only{ return expression ; }
- null statements,
- static_assert-declarations,
- typedef declarations and alias-declarations that do not define classes or enumerations,
- using-declarations,
- using-directives,
- and exactly one return statement.
every constructor call and implicit conversion used in converting expression to the function return type initializing the return value (6.6.3 [stmt.return], 8.5 [dcl.init]) shall be one of those allowed in a constant expression (5.19 [expr.const]).
7.1.5/5:the compound-statement of its function-body shall be emptycontain only
- null statements,
- static_assert-declarations,
- typedef declarations and alias-declarations that do not define classes or enumerations,
- using-declarations,
- and using-directives.
Function invocation substitution for a call of a constexpr function or of a constexpr constructor means implicitly converting each argumentexpressionto the corresponding parameter type as if by copy-initialization [ Footnote: ... --end footnote], substituting that converted expression for each use of the corresponding parameter in the function-body, and, for constexpr functions, implicitly converting the resulting returned expression or braced-init-list to the return type of the function as if by copy-initialization. Such substitution does not change the meaning. [ Example: ... --end example]For a constexpr function, if no function argument values exist such that the function invocation substitution would produce a constant expression (5.19 expr.const), the program is ill-formed; no diagnostic required. For a constexpr constructor, if no argument values exist such that after function invocation substitution, every constructor call and full-expression in the mem-initializers would be a constant expression (including conversions), the program is ill-formed; no diagnostic required.