Магические аргументы в шаблонах функций

В следующем коде

#include template void cal_size(T (&a)[N]) { std::cout<<"size of array is: "<<N<<std::endl; } int main() { int a[]={1,2,3,4,5,6}; int b[]={1}; cal_size(a); cal_size(b); } 

Как и ожидалось, размер обоих массивов печатается. Но как N автоматически получает инициализацию до правильного значения размера массива (массивы передаются по ссылке)? Как работает вышеуказанный код?

N не получает «инициализировано» ни к чему. Это не переменная. Это не объект. N – константа времени компиляции. N существует только во время компиляции. Значение N а также фактическое значение T определяется процессом, называемым выводом аргумента шаблона . И T и N выводятся из фактического типа аргумента, который вы передаете в свою функцию шаблона.

В первом вызове тип аргумента – int[6] , поэтому компилятор выводит, что T == int и N == 6 , генерирует для него отдельную функцию и вызывает ее. Назовем его cal_size_int_6

 void cal_size_int_6(int (&a)[6]) { std::cout << "size of array is: " << 6 << std::endl; } 

Обратите внимание, что в этой функции больше нет T и нет N Оба они были заменены их фактическими выведенными значениями во время компиляции.

В первом вызове тип аргумента - int[1] , поэтому компилятор выводит, что T == int и N == 1 генерирует отдельную функцию для этого и вызывает его. Назовем его cal_size_int_1

 void cal_size_int_1(int (&a)[1]) { std::cout << "size of array is: " << 1 << std::endl; } 

То же самое и здесь.

Ваш main смысл

 int main() { int a[]={1,2,3,4,5,6}; int b[]={1}; cal_size_int_6(a); cal_size_int_1(b); } 

Другими словами, ваш шаблон cal_size две разные функции (так называемые специализации исходного шаблона), каждая из которых имеет cal_size NT ) в теле. Вот как работают шаблоны на C ++.

Он работает, потому что тип a является «массивом длины 6 из int », а тип b – «массив длины 1 из int ». Компилятор знает это, поэтому он может вызывать правильную функцию. В частности, первый вызов вызывает экземпляр шаблона cal_size<6>() а второй вызов вызывает cal_size<1>() , поскольку это единственные экземпляры шаблонов, которые соответствуют их соответствующим аргументам.

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

 cal_size(a); // ok, compiler figures out implicitly that N=6 cal_size(a); // also ok, same result as above cal_size(a); // ERROR: a is not of type "array of length 5 of int" 

когда вы объявляете int a [] = {1,2,3}, это то же самое, что (или будет переписано как) int a [3] = {1,2,3}, поскольку шаблонная функция получает аргумент в форме T a [N], то N будет иметь значение 3.

  • Нестандартные параметры шаблона
  • использование имени classа в шаблоне classа без параметров шаблона
  • Можете ли вы рекомендовать механизм шаблонов .net?
  • Вывод типа параметра шаблона c ++
  • Что такое Mixins (как концепция)
  • Каковы некоторые параметры шаблона шаблона?
  • Вычисление шаблона для функции на основе возвращаемого типа?
  • Распространение «typedef» из основанного на производный class для «шаблона»
  • Как избежать ярких тегов шаблона?
  • Код рефакторинга, чтобы избежать
  • Специализация шаблона и проблемы с enable_if
  • Interesting Posts

    Добавление модульных тестов к устаревшему коду

    Зарядное устройство HP с ноутбуком Dell

    Безопасная отправка электронной почты с помощью Thunderbird?

    Как установить Notepad ++ в качестве редактора по умолчанию?

    presentRequestsDialogModallyWithSession не работает, но дает хороший результат

    Как инициализировать std :: array элегантно, если T не является конструктивным по умолчанию?

    Какие инструменты статического анализа доступны для C #?

    Как я могу запланировать запуск кода каждые несколько часов в инфраструктуре Elixir или Phoenix?

    Графическая библиотека .NET вокруг?

    Как получить текущий URL-адрес вкладки для расширения chrome?

    Есть ли браузер, эквивалентный ClearAuthenticationCache IE?

    Транспонирование кадра данных

    Как отключить кнопку в диалоговом окне jQuery из функции?

    Не удалось запустить приложение в Simulator: во время работы была обнаружена ошибка (Domain = LaunchServicesError, Code = 0)

    Строковый вывод: формат или concat в C #?

    Давайте будем гением компьютера.