Given this struct:
struct Foo {
std::array<int, 8> bar;
};
How can I get the number of elements of the bar array if I don't have an instance of Foo?
You may use std::tuple_size:
std::tuple_size<decltype(Foo::bar)>::value
std::tuples (std::tuple_size, std::tuple_element, std::get) have handy specializations to treat an std::array<T, N> like a std::tuple<T, T, ..., T>.std::tuple_size_v<decltype(Foo::bar)>Despite the good answer of @Jarod42, here is another possible solution based on decltype that doesn't use tuple_size.
It follows a minimal, working example that works in C++11:
#include<array>
struct Foo {
std::array<int, 8> bar;
};
int main() {
constexpr std::size_t N = decltype(Foo::bar){}.size();
static_assert(N == 8, "!");
}
std::array already has a constexpr member function named size that returns the value you are looking for.
constexpr, in that sense std::tuple_size is a better answer because it doesn't require any construction or destruction in the non-constexpr case.std::tuple_size is a better choice. That said I'd probably do a using array_size = std::tuple_size for readability.std::move that doesn't move anything. What else? :-) (note: just joking)You could give Foo a public static constexpr member.
struct Foo {
static constexpr std::size_t bar_size = 8;
std::array<int, bar_size> bar;
}
Now you know the size of bar from Foo::bar_size and you have the added flexibility of naming bar_size to something more descriptive if Foo ever has multiple arrays of the same size.
static const, I don't find this a good answer.static constexpr member is really not the thing to complain about; it'll consume no space in instances and be completely optimised away in its translation unit (unless its address is taken, but then that would require an out-of-line definition, so).static constexpr is a magic number. This solution removes the magic number and solves the problem with one simple line.You could do it the same as for legacy arrays:
sizeof(Foo::bar) / sizeof(Foo::bar[0])
std::extent but this isn't an answer as this would still require constructing an instance.sizeof std::array<int, 4> may not equal sizeof int[4] that's an implementation detail. Moreover if you're going to construct the std::array then just use the size() membersizeof(Foo::bar) / sizeof(Foo::bar[0]). No instance of Foo needed.std::array mean that it must have the same size and layout as a raw array in reality, even if that's not explicitly required?std::array has a size() member anyway.Use:
sizeof(Foo::bar) / sizeof(int)
#include <iostream> #include <array> using namespace std; struct Foo { std::array<int, 8> bar; }; int main() { cout << sizeof(Foo::bar) / sizeof(int) << endl; cout << std::tuple_size<decltype(Foo::bar)>::value << endl; return 0; }You can use like:
sizeof Foo().bar
sizeofsizeof doesn't evaluate its operand, you could always just std::declval<Foo>().std::array is allowed to have padding
std::arraydoesn't shrink or grow. It will always be 8 constructed objects.std::array<int, 8>you ever have a container with 8 elements; you can set the value of 4 of this elements (after the initialization) but the other 4 are present with initial value