考虑下面的代码:
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;
}
它不能编译为ref[0]
不是一个常量表达式。
无论如何,下面的代码编译得很好:
template<int N>
constexpr auto f(const char (&ref) [N]) {
return ref[0];
}
int main() {
constexpr auto v = f("foo");
(void)v;
}
他们是否应该出于或多或少相同的原因编译或失败?
从[expr.const]我们得到:
条件表达式
e
是核心常量表达式,除非e
[...] 的评估将评估以下表达式之一:
[...]
- 一个 id 表达式,它引用引用类型的变量或数据成员,除非引用有一个前面的初始化并且要么
- 它用一个常量表达式初始化,要么 - 它
的生命周期开始于e
;
无论如何,在这种情况下,它是用常量表达式初始化的,并且生命周期与 相同e
,因此该规则不适用。
我的推理有什么问题?
作为一个附带问题,我会问是否可以使用这样的数组或其中的一部分作为模板参数。