简体   繁体   English

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

[英]Using a constexpr static member of a reference as template argument

I'm trying to figure out whether GCC or Clang interpret the C++17 standard differently / wrong here.我试图弄清楚 GCC 或 Clang 是否在这里以不同的方式/错误地解释了 C++17 标准。

This is my code, which does compile using GCC 8, but not using Clang 6:这是我的代码,它使用 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
}

I wonder why that is.我不知道这是为什么。 Obviously, bb is a valid constexpr (or the first Foo<bb> wouldn't be valid).显然, bb是一个有效的 constexpr (或者第一个Foo<bb>将无效)。 Is br.b not a valid constexpr? br.b不是有效的 constexpr 吗? Why?为什么? The object or the reference itself should have nothing to do with it, since we're accessing a static constexpr member here, right?对象或引用本身应该与它无关,因为我们在这里访问的是静态 constexpr 成员,对吗?

If this is really not valid C++17, should the fact that GCC doesn't even warn me (even though I enabled -Wall -Wextra -pedantic ) be considered a bug?如果这真的不是有效的 C++17,那么 GCC 甚至没有警告我的事实(即使我启用了-Wall -Wextra -pedantic )是否应该被视为错误?

Clang is correct.叮当是对的。 References are evaluated "eagerly" in constant expressions, so to speak.可以这么说,引用在常量表达式中被“热切地”评估。 [expr.const]/2.11: [expr.const]/2.11:

An expression e is a core constant expression unless the evaluation of e, following the rules of the abstract machine, would evaluate one of the following expressions:表达式e是核心常量表达式,除非按照抽象机器的规则对 e 求值会求值以下表达式之一:

  • [...] [...]
  • an id-expression that refers to a variable or data member of reference type unless the reference has a preceding initialization and either引用变量或引用类型数据成员的id 表达式,除非该引用具有前面的初始化并且
    • it is initialized with a constant expression or它用常量表达式初始化或
    • its lifetime began within the evaluation of e ;它的生命周期从e的求值开始;
  • [...] [...]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM