Мой первый выбор будет std::variant
(лучше, чем std::optional
, поскольку он может предоставить дополнительную информацию в случае ошибки, и это всегда полезно в будущем):
usign ErrorType = int;
using ReturnType = std::variant<std::vector<int>, ErrorType>
ReturnType function() {
std::vector ans;
//do stuff
if (something happens)
return -1;
return ans;
}
Если ваша ошибка довольно редкая, а исключение может быть кашлем на более глубоком уровне вызывающего, то исключение также является хорошим / лучшим способом:
class MyException : public std::exception {
public:
MyException(int errorCode) : exception("MyException"), errorCode(errorCode)
{}
int code() const { return errorCode; }
private:
int errorCode;
};
std::vector<int> function() {
std::vector ans;
//do stuff
if (something happens)
throw MyException{ -1 };
return ans;
}
Пожалуйста, помните, что в C ++ исключения проектируются таким образом, что они обходятся без затрат, когда ничего не выбрасывается. Суть в том, что когда выдается что-то исключение, разматывание стека происходит крайне медленно (на каком-то cpp-con кто-то сказал, что оно медленнее в x40, я не измерял это). По этой причине использование std::optional
или std::variant
вместо исключения может быть столь полезным.
Стандартное сообщество AFAIK работает над механизмом исключений нового типа , который будет вести себя как std::variant
(аналогично тому, как это сделано в Swift).