Эффективный и современный С++. 42 рекомендации по использованию С++11 и С++14 | страница 19



и передадим ему массив

>f(name); // Передача массива функции f

то тип, выведенный для , будет в действительности типом массива! Этот тип включает размер массива, так что в нашем примере выводится как >const char[13], а типом параметра >f (ссылки на этот массив) является >const char (&)[13]. Да, выглядит этот синтаксис как наркотический бред, но знание его прибавит вам веса в глазах понимающих людей.

Интересно, что возможность объявлять ссылки на массивы позволяет создать шаблон, который выводит количество элементов, содержащихся в массиве:

>// Возвращает размер массива как константу времени компиляции.

>// Параметр не имеет имени, поскольку, кроме количества

>// содержащихся в нем элементов, нас ничто не интересует.

>template

>constexpr std::size_t arraySize(T (&)[N]) nоехсерt {

> return N;

>}

Как поясняется в разделе 3.9, объявление этой функции как >constexpr делает ее результат доступным во время компиляции. Это позволяет объявить, например, массив с таким же количеством элементов, как и у второго массива, размер которого вычисляется из инициализатора в фигурных скобках:

>// keyVals содержит 7 элементов:

>int keyVals[] = { 1, 3, 7, 9, 11, 22, 35 };


>int mappedVals[arraySize(keyVals)]; // mappedVals - тоже

Конечно, как разработчик на современном С++ вы, естественно, предпочтете >std::array встроенному массиву:

>// Размер mappedVals равен 7

>std::arrayarraySize(keyVals)> mappedVals;

Что касается объявления >arraySize как >noexcept, то это помогает компилятору генерировать лучший код. Детальнее этот вопрос рассматривается в разделе 3.8.

Аргументы-функции

Массивы — не единственные сущности в С++, которые могут превращаться в указатели. Типы функций могут превращаться в указатели на функции, и все, что мы говорили о выводе типов для массивов, применимо к выводу типов для функций и их преобразованию в указатели на функции. В результате получаем следующее:

>void someFunc(int, double); // someFunc - функция;

>                            // ее тип - void (int, double)


>template

>void f1(Т param);           // В f1 param передается по значению


>template

>void f2(T& param);          // В f2 param передается по ссылке


>f1(someFunc);               // param выводится как указатель на

>                            // функцию; тип - void (*)(int, double)


>f2(someFunc);               // param выводится как ссылка на

>                            // функцию; тип - void(&)(int,double)