Join the Stack Overflow Community
Stack Overflow is a community of 6.5 million programmers, just like you, helping each other.
Join them; it only takes a minute:
Sign up

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?

share|improve this question
2  
how about using a macro instead of hardcoding the array size? – Webert S. Lima 21 hours ago
8  
@WebertS.Lima - Perish the thought. Not a macro. – StoryTeller 21 hours ago
6  
@WebertS.Lima - std::array doesn't shrink or grow. It will always be 8 constructed objects. – StoryTeller 21 hours ago
3  
@WebertS.Lima - No; if you declare a 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 – max66 20 hours ago
2  
Also, the array doesn't exist yet, I sure hope it's not half-full. – Carl 6 hours ago
up vote 53 down vote accepted

You may use std::tuple_size:

std::tuple_size<decltype(Foo::bar)>::value
share|improve this answer
4  
Hooking this here: the various classes and functions dealing with 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>. – Quentin 20 hours ago

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.

share|improve this answer
2  
so this has the same issue as @waxrat's answer below, it requires construction even if that construction may be 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. – Mgetz 20 hours ago
3  
@Mgetz I didn't say it's better. :-) ... Different solutions and answers can help future readers, no matter if they are the accepted ones or not. – skypjack 20 hours ago
    
hence my comment, I sought to ensure such readers would understand why std::tuple_size is a better choice. That said I'd probably do a using array_size = std::tuple_size for readability. – Mgetz 20 hours ago
2  
@Mgetz Names aren't the strongest feature of the language, I agree. We are dealing with a language that contains a function named std::move that doesn't move anything. What else? :-) (note: just joking) – skypjack 20 hours ago

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.

share|improve this answer

You could do it the same as for legacy arrays:

sizeof(bar) / sizeof(bar[0])
share|improve this answer
2  
or use the much more readable std::extent but this isn't an answer as this would still require constructing an instance. – Mgetz 20 hours ago
2  
A few other things to keep in mind 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() member – Mgetz 20 hours ago
2  
I meant sizeof(Foo::bar) / sizeof(Foo::bar[0]). No instance of Foo needed. – Waxrat 20 hours ago
    
Works with g++ -Wall -Werror -std=c++11. – Waxrat 19 hours ago
    
@Mgetz Don't other, overt requirements of 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? – underscore_d 13 hours ago

Use:

sizeof(Foo::bar) / sizeof(int)
share|improve this answer
    
I tried and I am getting the same value for both. #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; } – Gilson PJ 20 hours ago
    
If you have a new question, please ask it by clicking the Ask Question button. Include a link to this question if it helps provide context. - From Review – Fabio 20 hours ago
    
@Jonasw: It does answer the question; it just does so poorly. – Lightness Races in Orbit 15 hours ago
4  
@Fabio: This is obviously not a "new question". – Lightness Races in Orbit 15 hours ago

You can use like:

sizeof Foo().bar
share|improve this answer
2  
See this comment from OP: he's after the number of elements, not the total size. – Quentin 21 hours ago
    
@Happy - the OP modified the answer: he want the number of elements in the array (8 in the example), not the sizeof – max66 21 hours ago
3  
note: won't work for classes without a default constructor – M.M 21 hours ago
    
@M.M Since sizeof doesn't evaluate its operand, you could always just std::declval<Foo>(). – Angew 20 hours ago
    
@Angew I couldn't get anything like that to work – M.M 20 hours ago

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.