Этого можно добиться с помощью шаблона функции.
template<class T>
T perform_operation(const T& left, std::string_view op, const T& right)
{
if (op == "+")
return left + right;
if (op == "-")
return left - right;
// ...
}
Теперь, когда std::string
не поддерживает operator -
и вы хотите, чтобы операция выдавала ошибку, вам нужно специализировать шаблон для этогоtype:
template<>
std::string perform_operation<std::string>(const std::string& left, std::string_view op, const std::string& right)
{
if (op == "+")
return left + right;
throw std::invalid_argument("std::string supports operator + only");
}
Это может быть создано и вызвано следующим образом:
const int result1 = perform_operation(1, "+", 2);
const float result2 = perform_operation(2.f, "-", 3.f);
const std::string result3 = perform_operation<std::string>("hello", "+", " world");
assert(result1 == 3);
assert(std::abs(result2 + 1.0f) < std::numeric_limits<float>::epsilon()));
assert(result3 == "hello world");
Обратите внимание, что я изменил типы аргументов, чтобы принимать операнды как const
-качественные ссылки иоператор как std::string_view
(функция C ++ 17), но последний не требуется.