Say I have a class that that can return a constant expression through a constexpr function:
template
struct Foo {
constexpr int Bar()
§5.20:
The reference does not have a preceding initialization from the point of view of i, though: It's a parameter. It's initialized once ByReference is called.
Let's remove the constexpr from i's declaration and consider an invocation of ByReference in its entirety:
template
constexpr int ByReference(const Foo &f) {
int i = f.Bar();
return i;
}
constexpr int j = ByReference(Foo<0>());
This is fine, since f does have preceding initialization. The initializer of f is a constant expression as well, since the implicitly declared default constructor is constexpr in this case (§12.1/5).
Hence i is initialized by a constant expression and the invocation is a constant expression itself.