使用引用的constexpr静态成员作为模板参数

时间:2018-08-06 14:51:33

标签: c++ language-lawyer c++17

我想弄清楚是GCC还是Clang对C ++ 17标准的解释不同/错误。

这是我的代码,使用GCC 8进行编译,但不使用Clang 6:

struct BoolHolder {
    constexpr static bool b = true;
};

template<bool b>
class Foo {};

int main() {
    BoolHolder b;
    Foo<b.b> f; // Works

    BoolHolder & br = b;
    Foo<br.b> f2; // Doesn't work
}

我想知道为什么。显然,b.b是有效的constexpr(或第一个Foo<b.b>无效)。 br.b不是有效的constexpr吗?为什么?对象或引用本身应该与它无关,因为我们在这里访问静态constexpr成员,对吧?

如果这真的不是有效的C ++ 17,是否应该将GCC甚至不警告我(即使我启用了-Wall -Wextra -pedantic)这一事实也视为错误?

1 个答案:

答案 0 :(得分:10)

C语是正确的。可以这么说,引用以常量表达式“急切”地求值。 [expr.const] /2.11:

  

表达式e是核心常量表达式,除非求值   的e,遵循抽象机的规则,将评估一个   以下表达式之一:

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