I need to statically assert that the compile-time size of a non-constexpr data member of type std::array
, say arr_
, of a non-template class is equal to a given (externally provided) constant. The static assertion will be done from inside the class, meaning arr_
is accessible, but I cannot rely on any stored constant (nor a non-type template parameter) for its size. I.e., the assertion needs to rely solely on "some inspection" of the arr_
data member.
I would basically be done if the constexpr
std::array<>::size()
/std::array<>::max_size()
was static member functions (decltype(arr_)::size()
/decltype(arr_)::max_size()
) instead of a non-static member functions.
I have a working approach using function template argument deduction on a pointer-to-data-member for the arr_
member, but I'm wondering if there is an easier/neater approach.
#include <array>
#include <cstddef>
// Defined/provided from elsewhere.
constexpr std::size_t kArraySize = 12U;
constexpr std::size_t kAnotherArraySize = 12U;
template <typename T, typename U, std::size_t N>
constexpr std::size_t size_of_data_member_array(std::array<T, N> U::*) {
return N;
}
class Foo {
std::array<int, kArraySize> arr_;
static_assert(size_of_data_member_array(&Foo::arr_) == kAnotherArraySize, "");
};
int main() {}
The standard provides a static version of array::size
under the name tuple_size
:
#include <array>
#include <tuple> // for std::tuple_size_v
static_assert(std::tuple_size<decltype(arr_)>::value == kAnotherArraySize, "");
static_assert(std::tuple_size_v<decltype(arr_)> == kAnotherArraySize); // C++17
You can create an instance of an array with the same type of Foo::arr_
within the static assertion:
class Foo {
std::array<int, kArraySize> arr_;
static_assert(decltype(arr_){}.size() == kAnotherArraySize, "");
};
See this example.
Note: this works only if the array value type is a POD or has a default constexpr constructor.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With