Подтвердить что ты не робот

Вызов функции шаблона с пустыми скобками <>

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

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)
}

В приведенном выше случае параметр шаблона действительно необязателен?

4b9b3361

Ответ 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>