According to this answer apparently there is no good reason why structured bindings are not allowed to be constexpr, yet the standard still forbids it. In this case, however, shouldn't the use of the structured bindings inside the constexpr function also be prohibited? Consider a simple snippet:
#include <utility>
constexpr int foo(std::pair<int, int> p) {
auto [a, b] = p;
return a;
}
int main() {
constexpr int a = foo({1, 2});
static_assert(a == 1);
}
Both gcc and clang does not cause trouble compiling the code. Is the code ill-formed either way or is this one actually allowed?
In the case of function declaration, the
constexpr
specifier is an assertion made to the compiler that the function being declared may be evaluated in a constant expression, i.e. an expression that can be evaluated at compile-time. Nevertheless the object initialization inside a declaration does not need to haveconstexpr
inside its declaration specifier to be a constant expression.Shorter:
constexpr
function may imply constant expression but constant expression initialization does not need that the associated declaration has aconstexpr
specifier.You can check this in the C++ standard [dcl.constexpr]:
This is the evaluation of an expression that determines if an expression is a constant expression [expr.const]:
A declaration is not an expression, so an initialization of an object being declared is a constant expression irrespective of the presence or not of a
constexpr
specifier in the declaration.Finally, in [dcl.constexpr], it is specified that a
constexpr
function must be such that there exist parameters for which its body can be evaluated as a constant expression:When you declare
constexpr int a
the compiler expectsa
to be inialized by a constant expression and the expressionfoo({1,2})
is a constant expression, so your code is well formed.PS: Nevertheless, declaration specifiers (static, thread_local=>static) in the the declaration of function local variable implies that the function cannot be declared
constexpr
.