如何定义自定义跨平台size_t类型?

101*_*010 12 c++ size-t size-type c++11 c++03

std::size_t通常用于数组索引和循环计数.根据定义,std::size_t是sizeof运算符以及sizeof...运算符和alignof运算符的结果的无符号整数类型(自C++ 11起).它在以下标题中定义:

  • <cstddef>
  • <cstdio>
  • <cstdlib>
  • <cstring>
  • <ctime>
  • <cwchar>

据我了解,这些运算符返回的类型是实现定义的.

我想要的是定义一个自定义size_t,以避免从.cpp我的文件中的上述任何标题中提取不必要的东西,因为在我的文件中我只需要std::size_t.

在C++ 11及更高版本中,我认为我可以使用以下别名:

using size_t = decltype(sizeof(1));
Run Code Online (Sandbox Code Playgroud)

但是,我想以size_t便携/跨平台的方式为C++ 11之前的编译器定义一种类型.

那么有一种可移植的方式来定义size_t前C++ 11吗?

W.F*_*.F. 5

理论上,如果列出所有可能的(未签名)候选size_t者不会打扰您,您可以使用 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;
Run Code Online (Sandbox Code Playgroud)

[现场演示]


编辑:

解决方法的编译器分化unsigned long从unsigned long long尽管他们假定的事实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;
Run Code Online (Sandbox Code Playgroud)

[现场演示]