Using a constexpr static member of a reference as template argument

雨燕双飞 提交于 2019-12-19 17:41:10

问题


I'm trying to figure out whether GCC or Clang interpret the C++17 standard differently / wrong here.

This is my code, which does compile using GCC 8, but not using 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, b.b is a valid constexpr (or the first Foo<b.b> wouldn't be valid). Is br.b not a valid 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?

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?


回答1:


Clang is correct. References are evaluated "eagerly" in constant expressions, so to speak. [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:

  • [...]
  • an id-expression that refers to a variable or data member of reference type unless the reference has a preceding initialization and either
    • it is initialized with a constant expression or
    • its lifetime began within the evaluation of e;
  • [...]


来源:https://stackoverflow.com/questions/51710377/using-a-constexpr-static-member-of-a-reference-as-template-argument

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!