Reputation: 42899
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?
Upvotes: 14
Views: 1611
Reputation: 13988
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;
Upvotes: 5
Reputation: 238331
As far as I know, you've listed the only two cross-platform ways to get size_t
: Include the definition from standard header, or decltype (since C++11). But both are explicitly unavailable to you.
The third option is manual porting i.e. use pre-defined macros to detect the environment, and choose the correct typedef from a manually maintained list of typedefs. For example, on GCC you might use __SIZE_TYPE__
(however, consider the warning in the documentation that the macro should not be used directly and that it is not provided on all platforms). On other compilers you would use something else.
Upvotes: 4
Reputation: 394
Unfortunately, "implementation-defined" includes the header files, not just the compiler itself. If you look at [expr.sizeof], they seem to suggest just using this:
#include <cstddef>
Upvotes: 0