以下代码使用枚举成员test-compile
作为常量表达式,即作为模板参数。代码在gcc下编译,但不在clang(live demo)下编译。 Clang说“错误:非类型模板参数不是常量表达式”。
可以通过m
交换行// 1
来解决问题。因此,我的问题不是如何解决这个问题,而是哪个编译器是正确的。
A<tst<p>::m> a
答案 0 :(得分:3)
根据标准,Clang拒绝代码是正确的。
t2.m
是类成员访问表达式。 [expr.ref] / 1说:
[...]评估点或箭头前的后缀表达式;该 评估结果与 id-expression 一起, 确定整个后缀表达式的结果。
还有一个注释:
如果计算了类成员访问表达式,则表示子表达式 即使结果不需要确定,也会发生评估 整个后缀表达式的值,例如,如果 id-expression 表示静态成员。
因此,评估子表达式t2
。 [expr.const] /2.9表示表达式e
不能作为核心常量表达式,如果评估它会导致评估
id-expression ,它引用引用的变量或数据成员 除非引用具有先前的初始化和
,否则键入
- 使用常量表达式
初始化- 其生命周期始于
的评估范围内e
;
t2
是指不满足项目符号的引用类型变量,因此t2.m
不是常量表达式,因为它不是核心常量表达式。
N4594的所有引用,目前公布的工作草案。自C ++ 11以来,文本略有改变,但在这种情况下的含义是相同的。