通过引用调用constexpr方法 - 结果是一个常量表达式吗?

时间:2016-05-17 23:44:29

标签: c++ gcc clang language-lawyer constexpr

以下代码

#include <array>

void foo(const std::array<int, 42> &a)
{
  constexpr size_t S = a.size();
}

int main() {}

在GCC中编译正常,但无法使用以下错误消息进行编译

main.cpp:5:28: error: constexpr variable 'S' must be initialized by a constant expression
      constexpr size_t S = a.size();
                           ^~~~~~~~

与此同时,很多关于SO constexpr问题的帖子似乎暗示clang经常对constexpr有更好(更迂腐?)的支持。那么,在这种情况下哪个编译器是正确的?

请注意,一旦参考参数被pass-by-value参数替换,两个编译器都乐意接受代码。

1 个答案:

答案 0 :(得分:7)

[expr.const]/2

  

条件表达式 e核心常量表达式,除非   e的评估,遵循抽象机器的规则   ([intro.execution]),将评估以下表达式之一:

     
      
  • [...]
  •   
  • id-expression 引用引用类型的变量或数据成员,除非引用具有先前的初始化并且

         
        
    • 使用常量表达式
    • 初始化   
    • 其生命周期始于e;
    • 的评估范围内   
  •   
  • [...]
  •   

评估a.size()评估 id-expression a,其“引用引用类型的变量”并且没有先前的初始化。因此,它不是核心常数表达式,因此不是常量表达式。