I'm developing a library in C++ in order to give to developers an help to some tasks. Usually, in order to calculate the size of an array of integer (for example) in a dynamic way (without use #define SIZE or static int SIZE), I do sizeof(v) / sizeof(int). I'm trying to write a piece of code that can do for me that stuff automatically and I decided to call if lengthof. The code is here:
template <class T> int _typesize(T*) { return sizeof(T); }
#define lengthof(x) (sizeof(x) / _typesize(&x))
I use the template to get the type of the array, then I return its size in bytes. In GCC I know that it's possible to use typeof, so I can replace _typesize(&x) with sizeof(typeof(x)), but it's not possible on MSVC. _typesize is a compatible way, but I think that it can be expensive because it passes the pointer as copy. There is an elegant way to do this?
No need for macros for this task. If you have a conforming compiler
template<class T, size_t len>
constexpr size_t lengthof(T(&)[len]) {return len;}
//the parameter is an unnamed reference to a `T[len]`,
//where `T` is deduced as the element type of the array
//and len is deduced as the length of the array.
//similar to `T(*)[len]` in C, except you can pass the array
//directly, instead of passing a pointer to it.
//added benefit that if you pass a `T*` to it, it produces a compiler error.
Or if you're using Visual Studio which is not yet conforming...
template<class T, size_t len>
std::integral_constant<size_t, len> lengthof(T(&)[len]) {return {};}
//VC++ doesn't have constexpr, so we have to use `std::integral_constant` instead :(
//but how it works is 100% identical
If you want a more portable way, macros still work best:
#define lengthof(arr) sizeof(arr) / sizeof(arr[0])
//doesn't respect namespaces, evaluates arguments multiple times
//and if you pass a `T*` to it, it evaluates to `1` depending on context.
But to reiterate my comment, I would consider all of this bad code. Use std::vector
or std::array
.