std::size_t
is commonly used for array indexing and loop counting. By definition, std::size_t
is the unsigned integer type of the result of the sizeof
operator as well as the sizeof...
operator and the alignof
operator (since C++11). It's defined in the following headers:
<cstddef>
<cstdio>
<cstdlib>
<cstring>
<ctime>
<cwchar>
To my understanding, the type returned by these operators is implementation-defined.
What I want is to define a custom size_t
in order to avoid pulling unnecessary stuff from any of the headers mentioned above in a .cpp
file of mine, since in my file I only need std::size_t
.
In C++11 and above, I thought I could use the following alias:
using size_t = decltype(sizeof(1));
However, I'd like to define a size_t
type for pre-C++11 compilers in a portable/cross-platform way.
So is there a portable way to define size_t
for pre-C++11?
Well theoretically, if listing of all possible (unsigned) candidates for size_t
doesn't bother you, you could make use of SFINAE:
template <class T, class N = void, bool = sizeof(T) == sizeof(sizeof(T))>
struct TL {
typedef typename N::type type;
};
template <class T, class N>
struct TL<T, N, true> {
typedef T type;
};
typedef TL<unsigned short,TL<unsigned int, TL<unsigned long, TL<unsigned long long> > > >::type SizeT;
Edit:
Workaround for compilers which differentiate unsigned long
from unsigned long long
despite the fact that they're assuming sizeof(unsigned long) == sizeof(unsigned long long)
:
template <class U>
U *declptrval(U);
template <class U>
char is_exact(U *);
template <class U>
short is_exact(...);
template <class T, class N = void, bool = sizeof(is_exact<T>(declptrval(sizeof(T))))==sizeof(char)>
struct TL {
typedef typename N::type type;
};
template <class T, class N>
struct TL<T, N, true> {
typedef T type;
};
typedef TL<unsigned short,TL<unsigned int, TL<unsigned long, TL<unsigned long long> > > >::type SizeT;