This answer truly depends on who is going to use your code, and what standards they want to see.
size_t is an integer size with a purpose:
size_t is an implementation-defined unsigned integer type that is large enough to contain the size in bytes of any object. (C++11 specification 18.2.6)
Thus, any time you wish to work with the size of objects in bytes, you should use
size_t. Now in many cases, you're not using these dimensions/indexes to count bytes, but most developers choose to use
size_t there for consistency.
Note that you should always use
size_t if your class is intended to have the look and feel of a STL class. All of the STL classes in the specification use
size_t. It is valid for the compiler to typedef
size_t to be
unsigned int, and it's also valid for it to be typedefed to
unsigned long. If you use
long directly, you'll eventually run into compilers where a person who thinks your class followed the STL's style gets trapped because you didn't follow the standard.
As for using signed types, there's a few advantages:
- Shorter names -- it's really easy for people to type
int, but much harder to clutter the code with
- One integer for each size -- There is only one CLS compliant integer of 32-bits, which is Int32. In C++, there's two (
uint32_t). This can make API interoperability simpler
The big disadvantage of signed types is the obvious one: you lose half of your domain. A signed number cannot count as high as an unsigned number. When C/C++ came around, this was very important. One needed to be able to address the full capability of the processor, and to do that you needed to use unsigned numbers.
For the kinds of applications .NET targeted, there was not as strong of a need for a full-domain unsigned index. Many of the purposes for such numbers are simply invalid in a managed language (memory pooling comes to mind). Also, as .NET came out, 64-bit computers were clearly the future. We're a long way away from needing the full range of a 64-bit integer, so sacrificing one bit is not as painful as it was before. If you really need 4 billion indexes, you simply switch to using 64-bit integers. At worst, you run it on a 32 bit machine and it's a little slow.
I view the trade as one of convenience. If you happen to have enough computing power that you don't mind wasting a bit of your index type that you will never-ever-ever use, then it's convenient to just type
long and walk away from it. If you find you really wanted that last bit, then you probably should have paid attention to the signedness of your numbers.