So I am over simplifying what I am trying to do here, but basically I have a function that looks like this:
int perform_operation(int left, std::string op, int right) {
if (op == "+")
return left + right;
if (op == "-")
return left - right;
...
};
I want this function to be able to take in float
, int
, and string
as left and right arguments. If strings is passed in and the +
operator is used, the strings should be concatenated, if a operator that does not support strings, it should throw an error.
I also want the function to be able to return both float
, int
and string
.
Maybe this is impossible, if so please give me an advice on how to do this instead.
...
I am writing an interpreter if anyone is wondering.
You can achieve this with a function template.
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;
// ...
}
Now as std::string
does not support operator -
and you want the operation to throw an error, you need to specialize the template for this 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");
}
This can be instantiated and invoked like the following.
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");
Note that I have changed the argument types to accept the operands as const
-qualified references and the operator as std::string_view
(a C++17 feature), but the latter isn't required.
Not sure why the question is downvoted, because this makes perfect sense in C++.
What you need is a template
. Specifically, a function template.
template <typename T>
T perform_operation(T left, std::string op, T right) {
if (op == "+")
return left + right;
if (op == "-")
return left - right;
// ...
}
Of course, there's no operator-
for templates, so you can use an overload:
std::string perform_operation(std::string left, std::string op, std::string right) {
if (op == "+")
return left + right;
// ...
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.