如何static_assert std::array 成员的大小

How to static_assert the size of a std::array member

本文关键字:成员 array 如何 assert std static      更新时间:2023-10-16

我想明确说明成员变量的数组大小限制,以防止其他人意外地进行愚蠢的更改。 以下幼稚的尝试将无法编译:

struct Foo
{
    std::array< int, 1024 > some_array;
    static_assert( (some_array.size() % 256) == 0, "Size must be multiple of 256" );
    //^ (clang) error: invalid use of non-static data member 'some_array'
};

即使std::array::size是一个 constexpr,我也不能直接使用这样的static_assert,因为函数和我的成员变量都不是静态的。

我想出的解决方案是使用decltype(因为我不想对数组进行 typedef(,如下所示:

static_assert( (decltype(some_array)().size() % 256) == 0, "Size must be multiple of 256" );

这看起来像是默认构造一个右值,我不认为这是一个 constexpr

为什么会这样?

有没有更干净的方法来实现静态断言?

因为函数和我的成员变量都不是静态的。

右。问题是静态断言不能引用非静态成员,因为some_array.size()等效于this->some_array.size(),并且在类范围内没有this指针(仅在函数声明符和默认成员初始值设定项内部(。

但是,可以说decltype(array_size),因为这实际上并不是试图引用对象array_size或调用其成员函数,它只是查询类中声明的名称的类型。

这看起来像是默认构造一个右值,我不认为这是一个 constexpr。

array<int, N> 是文本类型,因此可以在常量表达式中构造。构造右值的事实并不重要,您可以构造文本类型并在常量表达式中对其调用 constexpr 成员函数。

array<std::string, N>这样的东西不能在那里使用,因为std::string不是文字类型,所以也不是array<string, N>.

有没有更干净的方法来实现静态断言?

标准特征std::tuple_size专门用于std::array因此您可以执行以下操作:

static_assert( std::tuple_size<decltype(some_array)>::value % 256) == 0,
               "Size must be multiple of 256" );

std::array::sizeconstexpr的,应该与static_assert一起使用,但是它在这个特定的上下文(即,在类定义中(不起作用,因为some_array是一个非静态成员变量。

对于此特定上下文,您可以使用自制类型特征在编译时获取大小,如下所示:

template<typename>
struct array_size;
template<typename T, std::size_t N>
struct array_size<std::array<T, N>> {
  static const std::size_t size = N;
};

static_assert为:

static_assert(array_size<decltype(some_array)>::size % 256) == 0, "Size must be multiple of 256" );

现场演示

相关文章: