Вызов функции шаблона с пустыми скобками <>
Я путаюсь с приведенным ниже шаблоном поведения, где он компилируется с помощью пустых угловых скобок (шаблон без параметров) с синтаксически, шаблон < > зарезервирован для обозначения явной специализации шаблона.
template <typename T> void add(T a, T b) { }
int main() {
add<>(10, 3); // compiles fine since both parameters are of same data type
add<>(10, 3.2); // Error: no matching function for call to add(int, double)
}
В приведенном выше случае параметр шаблона действительно необязателен?
Ответы
Ответ 1
template<>
зарезервирован для обозначения явной специализации шаблона.
Это означает разные вещи, в зависимости от контекста. Здесь это означает "использовать аргумент по умолчанию или выведенный", так же, как если бы вы просто сказали add
.
В первом случае оба аргумента функции имеют один и тот же тип, поэтому аргумент шаблона можно вывести как int
.
Во втором случае они имеют разные типы, поэтому аргумент шаблона не может быть выведен. Вы должны указать, что хотите, например. add<double>
, преобразуйте один аргумент функции в соответствие с другим или измените шаблон для параметризации каждого типа отдельно.
В приведенном выше случае параметр шаблона действительно необязателен?
Да, если его можно вывести из типов аргументов.
Ответ 2
В первом случае да, потому что это можно сделать с помощью стандартных правил. Во-вторых, нет, потому что они не могут - вам нужно написать что-то вроде:
add<float>(10, 3.2);
Ответ 3
У вас есть один параметр шаблона и два параметра функции разных типов. Вывод аргумента шаблона должен совпадать для обоих аргументов, но если вы укажете int и double, это не сработает. Причина в том, что выведенный аргумент должен иметь точное соответствие, а преобразования типов не рассматриваются.
Синтаксис
add<double>(10, 3.2);
явно принудило бы T
равным double
. В этом случае константа int
10
преобразуется в double
.
Вы также можете добавить еще одну перегрузку
template <typename T, typename U> void add(T a, U b) { }
и, возможно, ограничить использование SFINAE, требуя, чтобы is_convertible<T, U>