Страницы

Поиск по вопросам

воскресенье, 8 декабря 2019 г.

Непонятен принцип работы шаблонных функций

#cpp


Во время продвижения в своем обучении программированию плавно подошел к теме шаблонных
функций.


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



Объясните мне пожалуйста, зачем при указании названия функции
необходимо указывать еще и тип этой функции(напримерtemplate voidsort(){...}). Разве template  не
выполняет роль типа функции?
Тип формальных параметров функции определяется исходя из того, какие типы мы задаем
самостоятельно. Тогда о каких данных
различных типов идет речь в цитате, приведенной из книге, по которой
я занимаюсь?


Очень буду рад развернутым ответам, желательно с примерами. Заранее благодарю!
    


Ответы

Ответ 1



Тип формальных параметров функции определяется исходя из того, какие типы мы задаем самостоятельно. Тогда о каких данных различных типов идет речь в цитате, приведенной из книге, по которой я занимаюсь? Вы пишите обобщенный код, например: template T mul(T lv, T rv) { return (lv * rv); } , требуя, чтобы для типа Т была определена операция *, иначе - ошибка компиляции. При вызове данной функции с доменами разных типов, например так: mul(12, 22); // но не mul(12, 22) mul(12, 22); // [1] а вдруг ?) mul(12.0, 22.0) // но не mul(...) тип выведется автоматически, тип указывать не следует если на то нет явной причины[1]. Как это сделать проще (-std=c++11): template auto mul(T lv, T rv) -> decltype(T * T) { return (lv * rv); } Как это сделать проще (-std=c++14): template decltype(auto) mul(T lv, T rv) { return (lv * rv); } В данном контексте - неявное преимущество. Давайте посмотрим на следующий пример: template ? mul(T lv, U rv) { return (lv * rv); } Что будем выводить? T? U? :) Про вывод типов хорошо написано у Мейерса в книге Эффективный и современный C++ Объясните мне пожалуйста, зачем при указании названия функции необходимо указывать еще и тип этой функции(напримерtemplate void sort(){...}). Разве template не выполняет роль типа функции? Чтобы работал вывод типов ))) P.S. Как-то режет слух это выражение - "тип функции", сразу в воздухе чувствуется запах Haskell'a с Type -> Type ... Наверное, лучше употреблять термины вроде тип возвращаемого значения, типы параметров и т.д. Объясните мне пожалуйста, зачем при указании названия функции необходимо указывать еще и тип этой функции(напримерtemplate void sort(){...}). Разве template не выполняет роль типа функции? Не всегда параметры типа - типы, например: template constexpr size_t array_size(T(&)[N]) noexcept { return N; } Как видите, T понадобился только для того, чтобы вывести тип параметра функции, в теле же функции - ни одного упоминания. FIX.: template auto mul(T lv, T rv) -> decltype(/* T * T */ lv * rv) { return (lv * rv); }

Ответ 2



Объясните мне пожалуйста, зачем при указании названия функции необходимо указывать еще и тип этой функции Вы хотели сказать тип возвращаемого значения (у вас это void). Вообще-то для функций его всегда нужно указывать, этот случай не исключение. template указывает, что следующее далее определение зависит от типа, который в определении обозначен как type, но как именно зависит, не предписывает: будет ли type в типах аргументов, типе возвращаемого значения, в типе локальной переменной в теле функции, нескольких местах или не будет вовсе (такое тоже возможно). Тип формальных параметров функции определяется исходя из того, какие типы мы задаем самостоятельно. Тогда о каких данных различных типов идет речь в цитате, приведенной из книге, по которой я занимаюсь? Шаблонная функция сама по себе ещё не функция, у неё неполное определение. Эта неполнота ограничивается как раз параметрами шаблона, в вашем случае единственным типом type. Для разных наборов параметров (у вас — для разных типов) этот шаблон создаст ("инстанцирует") различные функции. А не одну-единственную. В совокупности один и тот же алгоритм действительно применяется с разными типами, но происходит это в разных функциях.

Ответ 3



Разве template не выполняет роль типа функции? Нет, оно является частью объявления шаблона, а не объявления функции. Тип возвращаемого значения в примере — void. Тогда о каких данных различных типов идет речь в цитате, приведенной из книге, по которой я занимаюсь? Достаточно немного усложнить пример и фраза из книги сразу станет очевидна: template void sort_des(Type *arr, size_t sz) { for (size_t i=0; i

Ответ 4



Ну а если я напишу такой простой пример: #include #include using namespace std; template < class tp > void f() { cout << typeid(tp).hash_code(); } int main() { f(); f(); ... return 0; } Что вы тогда скажете?.. Тут функция имеет тип не возвращаюший ничего и не имеющий аргумент. Аргумент шаблона может выражать любую абстракцию, в том числе и тип возврата функции и тип аргументов функции и не иметь отношения ни к аргументам функции, ни к возвращающему типу. Не путайте инстанцирование шаблона по типу аргумента функции с типом функции. Компилятор не должен вместо вас решать что вы хотите получить в результате выполнения функции и какие аргументы вы хотите ей передать, а шаблонная функция определяется во время компиляции. Может кто то другой обьяснит получше. Я в этом плане не спец, но надеюсь вы кое что понели...

Комментариев нет:

Отправить комментарий