Как работает sizeof в этом помощнике для определения размера массива? - PullRequest
3 голосов
/ 24 мая 2011

Я нашел эту статью , которая вызывает следующий шаблон и макрос для получения размера массива:

template<typename Type, size_t Size>
char ( &ArraySizeHelper(Type( &Array )[Size]) )[Size];
#define _countof(Array) sizeof(ArraySizeHelper(Array))

, и я нахожу следующую часть совершенно неяснойsizeof применяется к объявлению функции.Я ожидаю, что результатом будет «размер указателя на функцию».Почему вместо этого он получает «размер возвращаемого значения»

Ответы [ 3 ]

6 голосов
/ 24 мая 2011

sizeof применяется к результату функции вызова , а не к объявлению. Поэтому он дает размер возвращаемого значения, которое в этом случае является ссылкой на массив символов.

Шаблон заставляет массив в возвращаемом типе иметь то же количество элементов, что и массив аргументов, который передается в функцию из макроса.

Наконец, sizeof затем применяется к ссылке на этот массив символов. sizeof для ссылки совпадает с sizeof для самого типа. Поскольку sizeof(char) == 1, это дает количество элементов в массиве.

5 голосов
/ 24 мая 2011
template<typename Type, size_t Size>
char (&ArraySizeHelper(Type(&Array)[Size]))[Size];
#define _countof(Array) sizeof(ArraySizeHelper(Array))

sizeof применяется к объявлению функции.Я ожидаю, что результатом будет «размер указателя на функцию».Почему вместо этого он получает «размер возвращаемого значения»?

Это не sizeof ArraySizeHelper (что было бы недопустимо - нельзя принимать sizeof функцию), ни sizeof &ArraySizeHelper - даже ненеявно, поскольку неявное преобразование из функции в указатель на функцию явно запрещено стандартом, для C ++ 0x см. 5.3.3).Скорее, это sizeof ArraySizeHelper(Array), что эквивалентно sizeof значению, которое возвращает вызов функции, то есть sizeof char[Size], следовательно, Size.

3 голосов
/ 24 мая 2011

ArraySizeHelper - это шаблон функции, который возвращает массив char размером Size.Шаблон принимает два параметра: один тип (который Type), а другой значение (который Size).

Поэтому, когда вы передаете объект типа, скажем, A[100] функции.Компилятор выводит оба аргумента шаблона: Type становится A, а Size становится 100.

Таким образом, тип возвращаемого экземпляра функции становится char[100].Поскольку аргумент sizeof никогда не вычисляется, поэтому функции не нужно иметь definition .sizeof нужно знать только тип возврата функции, которая равна char[100].Это становится эквивалентным sizeof(char[100]), который возвращает 100 - размер массива.

Еще один интересный момент, который следует отметить, заключается в том, что sizeof(char) не зависит от компилятора, в отличие от других примитивных типов (кроме вариантов символ 1 ).Его ВСЕГДА 1.Так что sizeof(char[100]) гарантированно будет 100.

1.Размер всех вариантов char - ОДИН, будь то char, signed char, unsigned char в соответствии со Стандартом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...