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

问题描述 投票:7回答:1

我试图弄清楚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)这个事实应该被认为是一个错误吗?

c++ language-lawyer c++17
1个回答
10
投票

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

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

  • [...]
  • 一个id-expression,引用引用类型的变量或数据成员,除非引用具有先前的初始化和任何一个 它是用常量表达式初始化的 它的生命始于e的评估;
  • [...]
© www.soinside.com 2019 - 2024. All rights reserved.