C++ Primer (5th edition) on page 240 has a note stating:
\"A
constexpr
function is not required to return a constant ex
A constexpr
function must return* must have a path that returns a constant expression iff all parameters are constant expressions. This actually makes sense. Example:
constexpr int square(int i){
return i*i;
}
std::array<int, square(2)> ia; //works as intended, constant expression
int i;
std::cin >> i;
int j = square(i); //works even though i is not a constant expression
std::array<int, square(i)> ia; //fails, because square does not (and cannot)
//return a constant expression
*Correction by chris.
A (non-template) constexpr
function must have at least one execution path that returns a constant expression; formally, there must exist argument values such that "an invocation of the function [...] could be an evaluated subexpression of a core constant expression" ([dcl.constexpr]/5). For example (ibid.):
constexpr int f(bool b) { return b ? throw 0 : 0; } // OK
constexpr int f() { return f(true); } // ill-formed, no diagnostic required
Here int f(bool)
is allowed to be constexpr
because its invocation with argument value false
returns a constant expression.
It is possible to have a constexpr
function that cannot ever return a constant expression if it is a specialization of a function template that could have at least one specialization that does return a constant expression. Again, with the above:
template<bool B> constexpr int g() { return f(B); } // OK
constexpr int h() { return g<true>(); } // ill-formed, no diagnostic required