#c
#c
Вопрос:
Предположим, что следующий код:
template<typename T>
void print(T in){
std::cout << in << std::endl;
}
Можно использовать оба следующих способа:
print(5);
print<int>(5);
Так являются ли типы необязательными или есть причина для их использования?
Комментарии:
1. Дело в том, чтобы иметь место вычет. Так что тогда
print(5)
andprint(5L)
вызовет соответственноprint<int>
andprint<long>
. Имейте в виду, что бывают случаи, когда вы хотите вручную указать тип.2. @DeiDei Это не ваш выбор, а то, что я чувствую, это небольшая трещина в красоте самого языка. «Имейте в виду, что есть случаи «… На месте!
Ответ №1:
Существует механизм, называемый вычетом аргументов шаблона. Из cppreference:
Чтобы создать экземпляр шаблона функции, каждый аргумент шаблона должен быть известен, но не каждый аргумент шаблона должен быть указан. Когда это возможно, компилятор выводит отсутствующие аргументы шаблона из аргументов функции. Это происходит при попытке вызова функции, когда берется адрес шаблона функции и в некоторых других контекстах: […]
В вашем примере компилятор может вывести аргумент шаблона T
, потому 5
что это int
. Следовательно void print<int>(int in)
, вызывается.
Так являются ли типы необязательными или есть причина для их использования?
Иногда вам все равно нужно явно указывать аргументы шаблона. Например, если вы хотите, чтобы произошло какое-либо преобразование, вы можете вызвать
print<double>(5);
print<int>(5.3); // prints 5
Справедливо ли то же самое для классов шаблонов?
До C 17 было обычным иметь шаблоны функций для создания экземпляров шаблонов классов. Посмотрите в std::make_pair
качестве примера. Без этого не было возможности исключить аргументы шаблона
auto x = std::pair(1,2); // before c 17: error missing template arguments
auto x = std::pair<int,int>(1,2); // OK
auto x = std::make_pair(1,2); // OK deduces std::make_pair<int,int>
Начиная с C 17 существует вывод аргумента шаблона класса, который позволяет вам писать:
std::pair p(2, 4.5); // deduces to std::pair<int, double> p(2, 4.5);
Комментарии:
1. Значит, тогда нет необходимости использовать их для функций, и я полагаю, что это будет работать как перегруженная функция? Справедливо ли то же самое для классов шаблонов?