为什么引用上的constexpr函数不是constexpr?

时间:2019-01-10 08:52:50

标签: c++ language-lawyer constant-expression

考虑以下功能:

Listener

在使用clang 6.0以及-std = c ++ 17进行编译时,此函数无法编译,因为数组上的size成员函数由于是引用而不是constexpr。错误消息是这样的:

  

错误:非类型模板参数不是常量表达式

当参数不是 引用时,代码将按预期工作。

我想知道为什么会这样,因为size()实际上返回了模板参数,因此几乎不可能再是const了。该参数是否为引用都无济于事。

我知道我当然可以使用S1和S2模板参数,该功能只是问题的简短说明。

标准中有什么吗?令我惊讶的是编译错误。

3 个答案:

答案 0 :(得分:3)

因为您已经评估了参考文献。来自Demo

  

表达式e是核心常量表达式,除非按照抽象机的规则对e的求值将对以下表达式之一求值:

     
      
  • ...
  •   
  • 一个 id-expression ,它引用引用类型的变量或数据成员,除非引用具有前面的初始化且      
        
    • 它可用于常量表达式或
    •   
    • 其寿命始于e的评估;
    •   
  •   
  • ...
  •   

您的参考参数没有预先初始化,因此无法在常量表达式中使用。

您可以在此处直接使用S1 + S2

答案 1 :(得分:3)

有关此问题的报告了一个错误,标题为numpy.ma

其中的讨论指出这并不是一个错误。

  

除非对e求值,否则表达式e是核心常数表达式。   e,遵循抽象机的规则,将评估以下内容之一   以下表达式:

     
      
  • [...]
  •   
  • 引用引用类型的变量或数据成员的id表达式,除非引用具有前面的初始化和   要么      
        
    • 使用常量表达式或
    • 进行初始化   
    • 其寿命始于e的评估;
    •   
  •   
  • [...]
  •   

以上引文摘自n4659草案的[expr.const] /2.11,并强调了重点。

答案 2 :(得分:0)

不幸的是,该标准指出,在类成员访问表达式中,对点或箭头之前的后缀表达式进行了评估; 63 [expr.ref]/1。后缀表达式是a中的a.b。该注释真的很有趣,因为这里就是这种情况:

  

63)如果评估了类成员访问表达式,则即使不需要确定整个后缀表达式的值(例如,如果id表达式表示静态成员),也将进行子表达式评估。

所以data也会被求值,即使常量表达式的规则也适用于它。