C++ 将“constexpr”与数组初始化一起使用

C++ 将“constexpr”与数组初始化一起使用,c++,arrays,c++11,constexpr,C++,Arrays,C++11,Constexpr,我知道在C++11中,我可以编写 class foo { static constexpr const char *one = "one"; } 但是,当我尝试对数组执行相同操作时 class bar { static constexpr const float prim[4] = {2, 3, 5, 7}; } (稍后再引用)我得到一个未定义的引用链接器错误 这对于数组来说是不可能的,还是我在语法中遗漏了什么?静态constepr数据成员声明不是C++11/14中的定义,因

我知道在C++11中,我可以编写

class foo {
    static constexpr const char *one = "one";
}
但是,当我尝试对数组执行相同操作时

class bar {
    static constexpr const float prim[4] = {2, 3, 5, 7};
}
(稍后再引用)我得到一个
未定义的引用
链接器错误


这对于数组来说是不可能的,还是我在语法中遗漏了什么?

静态constepr数据成员声明不是C++11/14中的定义,因此不能使用odr
prim

要解决此问题,请将以下语句放在cpp文件中的某个位置,就像处理任何其他非constexpr静态数据成员一样:

constexpr const float bar::prim[4];

换句话说,这将返回一个未定义的引用:

struct bar {
    static constexpr const float prim[4] = {2, 3, 5, 7};
};

int main() {
    auto *foo = bar::prim;
}
这并不是:

struct bar {
    static constexpr const float prim[4] = {2, 3, 5, 7};
};

constexpr const float bar::prim[4];

int main() {
    auto *foo = bar::prim;
}

因为在第二种情况下,您实际上是在定义
prim
,而不是声明它,因此您可以获得它的地址,通过引用使用它,等等……

这个示例的声明和用法在GCC 7.2上编译得很好。看看好的答案,在C++17中仍然需要它,什么允许在类中初始化内联变量?@RobertAndrzejuk在C++17(我引用标准)中,使用constexpr说明符声明的函数或静态数据成员隐式地是内联函数或变量。因此,C++17实际上改变了一切。