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

Luk*_*rth 8 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
}
Run Code Online (Sandbox Code Playgroud)

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

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

T.C*_*.C. 10

铿锵是对的.可以说,参考文献在常量表达式中"热切地"评估.[expr.const] /2.11:

表达式e是核心常量表达式,除非根据抽象机器的规则评估e将评估以下表达式之一:

  • [...]
  • 一个id-expression,引用引用类型的变量或数据成员,除非引用具有先前的初始化和任何一个
    • 它是用常量表达式初始化的
    • 它的生命始于评估范围内e;
  • [...]