Errors in C++
#include <iostream>
#include <stdexcept>
#include <string>
// In C++, we typically use exceptions for error handling, but we can
// simulate Go-style error returns using std::pair or a custom struct.
std::pair<int, std::string> f(int arg) {
if (arg == 42) {
// Instead of errors.New, we return a string as the error.
return {-1, "can't work with 42"};
}
// A empty string in the error position indicates that there was no error.
return {arg + 3, ""};
}
// We can use custom exception classes to represent specific error types.
class OutOfTeaError : public std::runtime_error {
public:
OutOfTeaError() : std::runtime_error("no more tea available") {}
};
class PowerError : public std::runtime_error {
public:
PowerError() : std::runtime_error("can't boil water") {}
};
void makeTea(int arg) {
if (arg == 2) {
throw OutOfTeaError();
} else if (arg == 4) {
// In C++, we can't directly wrap exceptions, but we can catch and rethrow
// with additional context.
try {
throw PowerError();
} catch (const PowerError& e) {
throw std::runtime_error(std::string("making tea: ") + e.what());
}
}
}
int main() {
for (int i : {7, 42}) {
auto [result, error] = f(i);
if (!error.empty()) {
std::cout << "f failed: " << error << std::endl;
} else {
std::cout << "f worked: " << result << std::endl;
}
}
for (int i = 0; i < 5; ++i) {
try {
makeTea(i);
std::cout << "Tea is ready!" << std::endl;
} catch (const OutOfTeaError& e) {
std::cout << "We should buy new tea!" << std::endl;
} catch (const PowerError& e) {
std::cout << "Now it is dark." << std::endl;
} catch (const std::exception& e) {
std::cout << "unknown error: " << e.what() << std::endl;
}
}
return 0;
}
This C++ code demonstrates error handling techniques that are similar to those used in the original example. Here are some key points:
We use
std::pair<int, std::string>
to simulate Go’s multiple return values for thef
function. The second element of the pair represents the error.Custom exception classes
OutOfTeaError
andPowerError
are used to represent specific error conditions, similar to sentinel errors in the original code.The
makeTea
function throws exceptions instead of returning error values.In the
main
function, we use a range-based for loop and structured bindings to handle the result off
.For error checking in
makeTea
, we use a try-catch block to handle different types of exceptions.The
dynamic_cast
is used to check for specific exception types, similar to theerrors.Is
function in the original code.
While C++ uses exceptions as its primary error-handling mechanism, this example shows how you can implement a error-return style similar to Go’s approach. However, it’s important to note that this is not idiomatic C++ and in real C++ code, you would typically use exceptions for error handling.