Что вы хотите std::common_type
:
template<typename T0, typename T1>
typename std::common_type<T0, T1>::type add(T0 a, T1 b) {
return a+b;
}
В документации говорится:
Для арифметических типов, общий тип можно рассматривать как тип (возможно смешанном режиме) арифметическое выражение таких как T0() + T1() + ... + Tn().
Но, как было отмечено на @ Jarod42 в комментариях, это просто мнение, и может быть неправильным в некоторых случаях, например, std::common_type<char, char>::type
является char
в то время как арифметическое выражение char() + char()
дает int
.
Более полная реализация может явно привести результат, чтобы удалить возможные предупреждения в случаях, упоминавшимися выше:
template<typename T0, typename T1, typename R = std::common_type_t<T0, T1>>
R add(T0 a, T1 b) {
return static_cast<R>(a+b);
}
Здесь std::common_type
используются по умолчанию для типа возвращаемого значения, но, поскольку он является параметром шаблона вы можете указать другой тип при использовании функции (может быть полезным в более сложных случаях использования):
char a = 1, b = 2;
add<decltype(a), decltype(b), int>(a, b);
Использование std::conditional
и std::is_same
, еще более полное решение, предложенное @ Jarod42 в комментариях позволяет иметь шаблон R
в качестве первого параметра, и держать автоматический вычет для a
и b
:
template <typename R, typename T0, typename T1>
using ResType = std::conditional_t<
std::is_same<void, R>::value,
std::common_type_t<T0, T1>, // default
R // R was explicitly specified: use it
>;
template <typename R = void, typename T0, typename T1>
ResType<R, T0, T1> add(T0 a, T1 b)
{
return static_cast<ResType<R, T0, T1>>(a + b);
}
Использование:
char a = 1, b = 2;
add(a, b); // returns char
add<int>(a, b); // returns int
Обратите внимание, что параметры шаблона обычно имеют верхний регистр по соглашению. – isanae