Ответ 1
Вы хотите 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