#c #boost
#c #повышение
Вопрос:
В boost/utility/swap.hpp
я нашел этот фрагмент кода:
template<class T, std::size_t N>
void swap_impl(T (amp; left)[N], T (amp; right)[N])
{
for (std::size_t i = 0; i < N; i)
{
::boost_swap_impl::swap_impl(left[i], right[i]);
}
}
Что такое left
и right
? Являются ли они ссылками на массивы? Разрешен ли этот код стандартом C ISO 2003 или более поздней версии?
Ответ №1:
Ссылка на массив типа T и длины N.
Это естественное расширение синтаксиса указателя на массив в C и поддерживается C 03.
Вы могли бы использовать cdecl.org чтобы попытаться проанализировать эти сложные объявления типов.
Комментарии:
1. Почему «статический»? У массивов может быть автоматический срок хранения. Суть в том, что это ссылка на массив, а не указатель на него.
2. @Steve: Я имею в виду, в отличие от динамического массива.
Ответ №2:
Что такое левое и правое? Являются ли они ссылками на массивы? Разрешен ли этот код стандартом C ISO 2003 или более поздней версии?
ДА. Это ссылки на массивы.
Это означает, что вы можете вызывать swap_impl
как:
int a[10]; //array
int b[10];
//...
swap_impl(a,b); //correct
Но вы не можете вызывать swap_impl
как:
int *a = new int[10]; //pointer
int *b = new int[10];
//...
swap_impl(a,b); //compilation error
Также обратите внимание, что вы не можете сделать даже это:
int a[10];
int b[11];
//...
swap_impl(a,b); //compilation error - a and b are arrays of different size!
Важный момент:
— Массивами должны быть не только аргументы, но и сами массивы одинакового размера!
Комментарии:
1. Почему «автоматический»? Массивы могут иметь статический срок хранения (например, глобальные). Суть в том, что это ссылка на массив, а не указатель на него.
Ответ №3:
Это способ объявить ссылку на массив из T (размера N) с именами left и right. Код является легальным C .
Это позволяет передавать в:
int ones[5] = { 1,1,1,1,1 };
int twos[5] = { 2,2,2,2,2 };
swap_impl(ones, twos);
Тогда вывод типа шаблона будет знать, что у вас есть T = int и N = 5, и произведет замену на месте. Если вы не соответствуете типам или размеру, вы получаете удобный сбой компиляции.
Ответ №4:
Да, это стандартный C , разрешенный с самого начала (это в основном C с добавлением ссылки).
Использование typedefs упрощает чтение:
int main()
{
typedef int (amp;MyArray)[4];
int data[4];
MyArray dataRef = data;
}
Это своего рода зеркальное отображение функции typedef
typedef int (*MyFunc)();