The C++ standard mentions this for std::size_t:
The type
size_tis an implementation-defined unsigned integer type that is large enough to contain the size in bytes of any object ([expr.sizeof]).
Now my question is that if this type is a distinct type from other unsigned int types or not. I mean, should I be able to have overloads like this or not:
void myfunc(std::uint16_t) {}
void myfunc(std::uint32_t) {}
void myfunc(std::uint64_t) {}
void myfunc(std::size_t) {}
Because if it is a distinct type, I should be able to have these overloads while if it is not, I should get redefinition error. I somehow always thought that std::size_t should be a distinct type but I currently get redefinition error which means it is not (at least in GCC and Clang)
The reason that I'm asking this is that I want to know if I have overload of a function for different unsigned int sizes, can I safely assume that one of them will be called for std::size_t or not.
Your question heavily depends on what exactly you mean with "unsigned int types". I'll assume this to refer to "unsigned integer types" as defined by the standard.
It can not be a type distinct from other unsigned integer types. All unsigned integer types are listed exclusively in [basic.fundamental]/2. These are the standard unsigned integer types
unsigned char,unsigned short,unsigned int,unsigned longandunsigned long long, and extended unsigned integer types if the implementation defines any (which isn't usually the case in the most common C++ implementations).If you intend "unsigned int types" to refer to the standard unsigned integer types listed above, then the answer becomes that
size_tis neither required, nor prohibited, to be one of them, since it may also be one of the extended unsigned integer types. But if the implementation has none of those, then it must be one of the standard unsigned integer types.If you intend "unsigned int types" to mean any "integer types" as defined in the standard which also have unsigned signdness, then the answer is again that it cannot be distinct from this set, since this set merely is a superset of the set of all unsigned integer types, adding
char8_t,char16_t,char32_tand potentiallycharandwchar_t(which have implementation-defined signdness).(You can find definitions for all the mentioned terms from the standard in [basic.fundamental]/1 to 11 of the post-C++20 ISO C++ draft N4868 I linked above.)
Regardless of the above, it is not guaranteed to cause a redefinition error, because while the types
uint16_t,uint32_tanduint64_talso must be unsigned integer types from the same category, they don't have to cover the whole category and in fact cannot, because there are at least 5 unsigned integer types, but you listed only threeuintX_toverloads. Sosize_tdoesn't need to match any of them and in fact doesn't need to match anyuintX_tat all.For example on 64bit architectures, often
uint16_tisunsigned short,uint32_tisunsigned intanduint64_tis eitherunsigned longorunsigned long long, with the remaining one not being aliased by anyuintX_t.So the overload set is not safe.
size_tmay be one of theuintX_tor it may not and neither the wholeuintX_tset, nor the whole set includingsize_tmust cover the set of all unsigned integer types.If you want to overload for all unsigned integer types, overload by the actual (non-alias) type names for the standard unsigned integer types listed above, as well as all extended unsigned integer types if your implementation has them. However, consider whether a template, possibly constrained with a type trait, isn't a better option instead, since you can't portably know about extended integer types.