使用枚举作为常量表达式。哪个编译器是对的?

时间:2016-07-15 14:20:36

标签: c++ c++11

以下代码使用枚举成员test-compile作为常量表达式,即作为模板参数。代码在gcc下编译,但不在clang(live demo)下编译。 Clang说“错误:非类型模板参数不是常量表达式”。

可以通过m交换行// 1来解决问题。因此,我的问题不是如何解决这个问题,而是哪个编译器是正确的。

A<tst<p>::m> a

1 个答案:

答案 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以来,文本略有改变,但在这种情况下的含义是相同的。