嵌套结构断裂constexpr尽管是相同的全球的人(Nested struct breaks con

2019-09-03 05:57发布

我在用下面的代码的麻烦:

template<typename T>
constexpr int get(T vec) {
  return vec.get();
}

struct coord {
  constexpr int get() const { return x; }
  int x;
};

struct foo {
    struct coord2 {
      constexpr int get() const { return x; }
      int x;
    };
    constexpr static coord f = { 5 };
    constexpr static int g = get(f); // works

    constexpr static coord2 h = { 5 };
    constexpr static int i = get(h); // doesn't work
};

constexpr coord foo::f;
constexpr foo::coord2 foo::h;

int main(){}

从本质上讲, get(f)被认为是一个常量表达式,但get(h)则不是。 唯一改变的是一个使用一个全球性的结构coord ,而其他使用嵌套结构coord2 。 该结构的身体是一样的。

为什么是这样?


GCC错误:

test.cpp:20:35: error: field initializer is not constant

锵错误:

test.cpp:20:26: error: constexpr variable 'i' must be initialized by a constant expression
    constexpr static int i = get(h); // doesn't work
                         ^   ~~~~~~
test.cpp:8:10: note: undefined function 'get' cannot be used in a constant expression
  return vec.get();
         ^
test.cpp:20:30: note: in call to 'get({5})'
    constexpr static int i = get(h); // doesn't work
                             ^
test.cpp:13:21: note: declared here
      constexpr int get() const { return x; }

Answer 1:

这是一个常量表达式....最终,因为这说明你可以通过移动看到i进入main()

  • http://ideone.com/lucfUi

该错误信息是很清楚是怎么回事,这是foo::coord2::get()还没有确定,因为成员函数定义被延迟,直到封闭类的末尾,以便他们可以使用会员后声明。

这是一个令人感到有点惊讶,该定义被延迟,直到最外层的课结束,但是如果你会更惊讶foo::coord2::get()无法访问foo::g

标准同意编译器,顺便说一句。 部分9.2p2的部分说

内的类成员-说明书中 ,类被认为是功能体 ,默认参数, 异常规格 范围内完成,及大括号或相等-初始化用于非静态数据成员(包括嵌套类这样的事情)。

不幸的是,这只是推断,类声明的右括号变成了这些延期区域点的定义。 我相信这是在标准的缺陷,它并没有明确说这一点。

也可以看看:

  • https://stackoverflow.com/a/11523155/103167


文章来源: Nested struct breaks constexpr despite being identical to global ones