4 ms·
No, because the expression is not evaluated at any time. Only the type of the expression is used. A much better implementation would be using std::begin,
by tines 11y ago
No, because the expression is not evaluated at any time. Only the type of the expression is used.
A much better implementation would be
using std::begin, std::end;
#define countof(x) (end(x) - begin(x))
(except for the double evaluation, but this is better as a template function instead of a macro anyway) because it'll work on any type that supports random-access iterators which include arrays but also std::array and vector.
- hendzen 11y agoThere is such a function in the STL already. http://en.cppreference.com/w/cpp/iterator/distance http://en.cppreference.com/w/cpp/iterator/distance
- stormbrew 11y agoCorrected below, leaving here for posterity and to make sure this conversation isn't confusing in the future. The only thing I'll note is that you get a compile error on a zero length array, so the OP of this chain turns out right in a way heh. Start ignoring here: Are you suggesting end() and begin() can be called on an array? As far as I know they can't. Apparently you can deduce array length in a constexpr function now in C++11 (which I only learned just now but also couldn't get working quickly, so have some salt with that), but before that arrays always degrade to pointers when passed as function arguments so there's (afaik) no way to extract their length from their type...
- hendzen 11y agoBefore the array decays to a pointer, you can get its length. Here is the implementation of std::begin for arrays in libc++: https://github.com/llvm-mirror/libcxx/blob/60d223df071f6e3d4ffa29331ed466fff563096f/include/iterator#L1430-L1436 https://github.com/llvm-mirror/libcxx/blob/60d223df071f6e3d4...
- stormbrew 11y agoQuite right, I'm apparently rusty on my stdlib knowledge. Didn't know about the reference trick.
- onedognight 11y agoYes you can call std::begin() and std::end() on an array. int a[] = {4,5,6}; for(int i : a) ; That is how the above works.
- kayamon 11y agoDoes this work at compile-time? One of the uses for countof is (somewhat ironically) doing a enum->string table where you want to enforce the table gets manually updated properly: enum Color { red, green, blue, num_colors }; const char *color_string[] = { "red", "green", "blue" }; static_assert(countof(color_string) == num_colors);
- tines 11y agoNo, it doesn't, which is why I said this is better implemented with a template :)