在数组声明中使用常量结构成员

Using constant struct members in array declaration

本文关键字:常量 结构 成员 数组 声明      更新时间:2023-10-16

我正在编写一个小玩具项目(一个数据结构),其中我有一个常量集合,我想将其捆绑在主类中的匿名结构中。这个类使用一些常量来声明静态数组的大小。它看起来像这样:

template< class T, size_t K >
class Tree {
    static struct {
        size_t const min_keys{ K };
        size_t const max_keys{ 2*K };
        ...
    } const constants;
    ...
};

K是模板形参,该结构体的所有成员都是const。然而,当声明一个静态数组时,编译器(我使用的是g++ 5.1)会报错。

bpt.h:34:34: error: size of array is not an integral constant-expression
     T keys[constants.max_keys];

这使我困惑-一切都是const。我只是试图清理我的常量,像这样捆绑它们似乎是理想和有趣的。使用枚举类也不错,但由于该类还需要与那些常量进行比较,因此不可能使用枚举类。现在我正在使用一个匿名枚举,它确实可以工作,但是这激起了我的好奇心。

为什么会这样?这是个坏主意吗?

我对c++非常陌生,如果有其他的选择我会很高兴。

下面的代码可以工作:

#include <cstddef>
#include <iostream>
template <typename T, std::size_t K>
struct Tree {
    static constexpr struct {
    //     ^^^^^^^^^
        std::size_t const min_keys{ K };
        std::size_t const max_keys{ 2*K };
    } constants {};
    //         ^^^
};

使用例子:

int main()
{
    int foo[Tree<int, 20>::constants.min_keys] = {1, 2};
}

关键是使Tree::constants成为constexpr静态数据成员,这意味着它的成员是常量表达式,可以用作数组大小。注意:

  • static constexpr成员需要初始化式,因此{}(或者我们可以把{K, 2 * K}放在这里,不使用大括号或等号初始化式)。

  • 你不需要一个静态constexpr成员的定义,只要你不过度使用它(例如,不要试图计算&Tree<int, 3>::constants)。