C ++ бросить исключение в функцию и поймать его в вызывающей? - PullRequest
1 голос
/ 03 июня 2019

У меня есть функция, которая возвращает «вектор».Однако иногда во время выполнения функция может столкнуться с ошибкой, при которой она не должна возвращать вектор, а вместо этого возвращает значение, которое может быть проверено вызывающей стороной.Должен ли я обработать это, выдав исключение и поймав его в вызывающей программе, или я должен изменить тип возвращаемого значения функции на «std :: pair», в котором хранится возвращаемое значение (0 или 1) и вектор.Я не хочу выходить из программы с ошибкой 'std :: runtime' в случае возникновения условий.

std::vector<int> function() {

std::vector ans;
//do stuff

if (something happens)
    return -1;

return ans;

}  

Ответы [ 3 ]

4 голосов
/ 03 июня 2019

Звучит как хорошее время для исключения. Создайте бросаемый тип, который может иметь аргумент конструктора, своего рода код, объясняющий проблему. Ловец может проверить этот код.

Люди предложат std::variant и тому подобное вместо этого, но это довольно быстро запутывается и приводит к всплытию подписи вашей функции. Это также усложняет код на месте вызова. Здесь нет необходимости. Исключения были буквально разработаны для этого варианта использования.

3 голосов
/ 03 июня 2019

Мой первый выбор будет 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).

0 голосов
/ 03 июня 2019

Вы можете использовать std::optional для него.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...