Нет Автоматическое преобразование из `int` в` float` с функцией шаблона
После нескольких лет кодирования в С++ сегодня мне задали простой вопрос, но я действительно не смог найти его ответ, и поэтому я ребята.
Кроме того, интересно, что почему эта ошибка происходит, я хочу знать , как, я могу решить ниже ошибку, изменив только функцию шаблона (без изменение функции main()
)
template <class T>
T Add(T first, T second)
{
return first + second;
}
int main()
{
auto sample_1 = Add(1, 2); // Works
auto sample_2 = Add(1.f, 2.f); // Works
auto sample_3 = Add(1.f, 2); // Error: no instance matches the argument types: (double, int)
return 0;
}
Ответы
Ответ 1
Кроме того, интересно узнать, почему эта ошибка происходит,
Когда вы вызываете Add(1.f, 2)
, первый тип аргумента - float
, а второй тип аргумента - int
.
Компилятор должен преобразовать либо первый аргумент в int
, либо второй аргумент в float
. Поскольку для обоих из них потребуется преобразование, они одинаково хороши. Нельзя быть предпочтительнее другого.
Я хочу знать, как я могу решить ниже ошибку, изменяя только функцию шаблона
Вы можете изменить шаблон функции:
template <class T1, class T2>
auto Add(T1 first, T2 second)
{
return first + second;
}
или (спасибо @PiotrSkotnicki):
template <class T>
T Add(T first, decltype(first) second)
{
return first + second;
}
В этом случае тип second
не выводится из аргумента, передаваемого функции. Тип first
выводится из первого аргумента, а тип second
вынужден быть таким же, как тип first
.
Add(1.2f, 2); // The first argument is deduced to be float
// The second argument is forced to be float.
Add(2, 1.2f); // The first argument is deduced to be int
// The second argument is forced to be int.
Ответ 2
Просто выполните:
template <class T1, class T2>
auto Add(T1 first, T2 second)
{
return first + second;
}
Как и в случае с уникальным T
, он выводится один раз как int
, один раз как double
...
Ответ 3
Если у вас
template <class T>
T Add(T first, T second)
тип first
и second
должен быть одинаковым. Если вы хотите использовать два разных типа, вы можете добавить второй параметр шаблона
template <class T1, class T2>
auto Add(T1 first, T2 second)
или для С++ 11
template <class T1, class T2>
auto Add(T1 first, T2 second) -> decltype(first + second)
Ответ 4
Компилятор пытается вывести тип шаблона, который он может использовать для создания функции, соответствующей сигнатуре. Поскольку параметры являются разными типами, он не может этого сделать.
Вы можете явно указать тип:
auto sample_3 = Add<float>(1.f, 2);
Но вы говорите, что не хотите этого делать.
Вы можете изменить функцию, чтобы взять два типа шаблонов:
template <class T1, class T2>
T1 Add(T1 first, T2 second)
{
T1 p;
p = first + second;
return p;
}
Но теперь вам нужно будет сделать предположение о том, какой тип будет возвращен.
Я никогда не пытался использовать auto
как возвращаемый тип, но, по-видимому, он работает: http://ideone.com/1qO95w
template <class T1, class T2>
auto Add(T1 first, T2 second)
{
auto p = first + second;
return p;
}
Ответ 5
Зачем писать свою собственную функцию, когда стандарт уже предоставил их?
В С++ 11 вы можете использовать:
#include <functional>
int main()
{
auto sample_1 = std::plus<float> () ( 1, 2 ); // Works
auto sample_2 = std::plus<float> () ( 1.f, 2.f ); // Works
auto sample_3 = std::plus<float> () ( 1.f, 2 ); // Works
return 0;
}
В С++ 14:
#include <functional>
int main()
{
auto sample_1 = std::plus<> () ( 1, 2 ); // Works
auto sample_2 = std::plus<> () ( 1.f, 2.f ); // Works
auto sample_3 = std::plus<> () ( 1.f, 2 ); // Works
return 0;
}
Ответ 6
Я хочу знать, как я могу решить ниже ошибку, изменяя только функцию шаблона
Вроде:
template <class T1, class T2>
T1 Add(T1 first, T2 second)
{
T1 p;
p = first + second;
return p;
}
int main()
{
auto sample_1 = Add(1, 2);
auto sample_2 = Add(1.f, 2.f);
auto sample_3 = Add(1.f, 2);
return 0;
}