Как определить пользовательский кроссплатформенный тип size_t?

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));

Тем не менее, я хотел бы определить size_t тип для компиляторов до C ++ 11 переносимым / кроссплатформенным способом.

Так есть ли портативный способ определить size_t для pre-C ++ 11?

12

Решение

Ну, теоретически, если список всех возможных (без знака) кандидатов на 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;

[живое демо]


Редактировать:

Обходной путь для компиляторов, которые различают 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;

[живое демо]

3

Другие решения

Насколько я знаю, вы перечислили только два кроссплатформенных способа получить size_t: Включить определение из стандартного заголовка или decltype (начиная с C ++ 11). Но оба явно недоступны для вас.

Третий вариант — это ручное портирование, то есть использование предопределенных макросов для обнаружения среды и выбор правильного typedef из списка поддерживаемых вручную typedef. Например, в GCC вы можете использовать __SIZE_TYPE__ (однако учтите в документации предупреждение о том, что макрос не следует использовать напрямую и что он не предоставляется на всех платформах). На других компиляторах вы бы использовали что-то еще.

4

К сожалению, «определяемый реализацией» включает в себя файлы заголовков, а не только сам компилятор. Если вы посмотрите на [Expr.sizeof], кажется, они предлагают просто использовать это:

#include <cstddef>
0
По вопросам рекламы [email protected]