C++ 嵌套结构会中断constexpr,尽管它与全局结构相同

C++ 嵌套结构会中断constexpr,尽管它与全局结构相同,c++,c++11,constexpr,C++,C++11,Constexpr,我在以下代码中遇到问题: 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

我在以下代码中遇到问题:

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(){}
叮当声错误:

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; }

这是一个不变的表达。。。。最后,如图所示,通过将
i
移动到
main()
,您可以看到:

错误消息非常清楚发生了什么,也就是说,
foo::coord2::get()
尚未定义,因为成员函数定义被延迟到封闭类的末尾,以便它们可以使用稍后声明的成员

定义延迟到最外层封闭类的末尾有点奇怪,但是如果
foo::coord2::get()
无法访问
foo::g
,您会更加惊讶

顺便说一句,该标准与编译器一致。第9.2p2节的一部分说

在类成员规范中,类在函数体、默认参数、异常规范以及非静态数据成员的大括号或相等初始值设定项(包括嵌套类中的此类内容)中被视为完整的

不幸的是,只能推断类声明的右括号成为这些延迟区域的定义点。我认为这是标准中的一个缺陷,它没有明确说明这一点

另见:


    • @dyp:我不是这么说的吗?(这是推断,它不是明确的)啊,好吧,我误解了那一段,对不起。@Somnium:把你的首字母缩写词移开?IIRC,您可以对
      const static
      数据成员使用
      constepr
      初始值设定项。
      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; }