Consider the code below:
template<char>
struct S { };
template<int N>
constexpr auto f(const char (&ref) [N]) {
return S<ref[0]>{};
}
int main() {
constexpr auto v = f("foo");
(void)v;
}
It doesn't compile for ref[0]
is not a constant expression.
Anyway, the code below compiles fine:
template<int N>
constexpr auto f(const char (&ref) [N]) {
return ref[0];
}
int main() {
constexpr auto v = f("foo");
(void)v;
}
Should both of them compile or fail to do that for more or less the same reason?
From [expr.const] we have that:
A conditional-expression
e
is a core constant expression unless the evaluation ofe
[...] would evaluate one of the following expressions:
[...]
- an id-expression that refers to a variable or data member of reference type unless the reference has a preceding initialization and either
- it is initialized with a constant expression or
- its lifetime began within the evaluation ofe
;
Anyway, in this case, it is initialized with a constant expression and the lifetime is the same of e
, thus the rule doesn't apply.
What's wrong in my reasoning?
As a side question, I would ask if it's possible to use such an array or part of it as a template argument.