如何强制具有与数组大小相同的项目数的数组初始化程序?

时间:2019-12-20 00:25:54

标签: c++

我最近发现了这个错误:

enum class MyEnum
{
    Enum1,
    Enum2,
    Enum3,
    Count
};
const char* names[MyEnum::Count] =
{
    "Enum1",
    "Enum2",
};

static_assert(sizeof_array(names) == MyEnum::Count, "Name count mismatch");

除非您将static_assert更改为names[MyEnum::Count],否则names[]不会断言。

是否有一种方法可以强制或检测具有显式大小的数组和初始化程序是否实际上初始化了整个数组,以防止此类错误?

2 个答案:

答案 0 :(得分:1)

添加一些凌乱的代码以检查此错误将防止该错误再次出现在同一位置,但不会阻止其他地方出现类似的错误。 如果这是您想要的,请考虑添加一个很好的注释:

// `names[]` is correct, changing it to `names[X]` is a mistake, refer to #123.
const char* names[] = { /* ... */ };

如果在许多地方都有类似的代码,请考虑编写自定义的clang整洁检查。

我自己从未写过自定义的clang整洁检查,但这似乎是可行的,并且听起来像是一个很好的长期解决方案。

答案 1 :(得分:0)

使用std::array,您可以执行以下操作:

template <std::size_t typename Cont, std::size_t ... Is>
auto make_array_impl(const Cont& c, std::index_sequence<Is...>)
{
    return std::array{c[Is]...};
}

template <std::size_t Expected, typename T, std::size_t N>
std::array<T, N> make_array(const T(&a)[N])
{
    static_assert(Expected == N);
    return make_array_impl(a, std::make_index_sequence<N>());
}

auto names = make_array<MyEnum::Count>({
    "Enum1",
    "Enum2",
}); // Assert fire at compile time

在不修改代码的情况下,您必须找到带有该警告的警告,或者编写自己的规则(lang语工具可能会有所帮助)。