#cpp
Во время продвижения в своем обучении программированию плавно подошел к теме шаблонных функций. С помощью шаблона функции можно определить алгоритм, который будет применяться к данным различных типов... Объясните мне пожалуйста, зачем при указании названия функции необходимо указывать еще и тип этой функции(напримерtemplatevoidsort(){...}). Разве template не выполняет роль типа функции? Тип формальных параметров функции определяется исходя из того, какие типы мы задаем самостоятельно. Тогда о каких данных различных типов идет речь в цитате, приведенной из книге, по которой я занимаюсь? Очень буду рад развернутым ответам, желательно с примерами. Заранее благодарю!
Ответы
Ответ 1
Тип формальных параметров функции определяется исходя из того, какие типы мы задаем самостоятельно. Тогда о каких данных различных типов идет речь в цитате, приведенной из книге, по которой я занимаюсь? Вы пишите обобщенный код, например: templateT 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; } Что вы тогда скажете?.. Тут функция имеет тип не возвращаюший ничего и не имеющий аргумент. Аргумент шаблона может выражать любую абстракцию, в том числе и тип возврата функции и тип аргументов функции и не иметь отношения ни к аргументам функции, ни к возвращающему типу. Не путайте инстанцирование шаблона по типу аргумента функции с типом функции. Компилятор не должен вместо вас решать что вы хотите получить в результате выполнения функции и какие аргументы вы хотите ей передать, а шаблонная функция определяется во время компиляции. Может кто то другой обьяснит получше. Я в этом плане не спец, но надеюсь вы кое что понели...
Комментариев нет:
Отправить комментарий