It seemed best to start another thread for this instead of derailing the thread the conversation started in and maybe to get some other opinions.
10 hours ago, a light breeze said:... but the sizeof(ARRAY)/sizeof(ARRAY[0]) trick for finding the length of an array has no place in C++.
5 hours ago, MagForceSeven said:... but I'm curious as to what the alternative would be? I'm not aware of any standard language feature that has replaced this particular trick.
...
The only one that I can think of would be never use static arrays and only ever use std::vector (or whatever dynamic array is available in your engine, like TArray in UE or whatever vector replacement EA STL has) and that just seems misguided. While I usually use the dynamic array that I have available, there are cases where that's just overkill or doesn't meet the compile-time requirements required.
I've mostly used this in combination with static_assert to validate (at compile time) that some static array size matches the length of an enumeration.
The old static assert trick was to define an array that had size 0 or 1 based on a compile-time boolean condition. If the condition was false, the array would be sized to 0 which is illegal and caused a compile error. That trick no longer has a place in modern C++ precisely because static_assert is now a language feature that directly provides the feature.
1 hour ago, a light breeze said:template<class T, std::size_t N> constexpr std::size_t array_size(T(&)[N]) noexcept { return N; }
Without the constexpr and noexcept, this has worked for as long as C++ has had templates.
That's definitely clever, but it feels like you're just trading one compiler trick for a different compiler trick. Do you think this one is better because it's somehow "more C++" than the sizeof version?
I have two issues with this code. Firstly I think it's too complicated and clever for it's own good. Even setting aside the new-ness of constexpr, this requires an understanding of templates and template parameter deduction that can take a while to understand. I have a hard enough time with other programmers doing templates right with trivial type deduction that this could make their head explode. Secondly, now that this is a function it's got to live somewhere which means either duplicating it in every header that uses it (bad) or putting it in it's own header (or a utilities header) and including it. This point is more personal preference than anything else since it feels like such a trivial operation to include a header for. I've definitely seen code that wraps the sizeof trick in a macro, but I think that's silly too since that has the same dependency problem as this function. I don't think many people would make a macro/function to wrap "+= 2" just because it happens to occur in multiple places in the code.
I don't want to come off as argumentative here @a light breeze. I'm not claiming to be right or that you're wrong or that there's even a right or wrong to be decided here. I'm honestly just very interested in the why of how people decided the things they find acceptable or not. And when someone uses a phrase like "has no place" I immediately want to explore that!