简体   繁体   中英

C++ throw an exception in a function and catch it in the caller?

I have a function that returns a 'vector'. However, sometimes during runtime the function can encounter an error in which it should not return the vector but instead return a value that can be checked by caller. Should I handle this by throwing an exception and catching it in the caller or should I change the return type of the function to 'std::pair' that stores a return value (0 or 1) and the vector. I don't want to exit the program with 'std::runtime 'error if the conditions occurs.

std::vector<int> function() {

std::vector ans;
//do stuff

if (something happens)
    return -1;

return ans;

}  

This sounds like a good time for an exception. Make a throwable type that can have a constructor argument, some sort of code that explains the problem. The catcher can check that code.

People will suggest std::variant and such instead, but that gets messy quite quickly and causes your function's signature to balloon. It also complicates the code at the callsite. There's no need for it here. Exceptions were literally designed for this use case.

My first choice would be a std::variant (it is better then std::optional since it can provide extra information in case of error and this is always beneficial in the future):

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;
}

If your error is quite rare and exception could be cough in deeper caller level then exception is also a good/better way:

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;
}

Please remember that in C++ exceptions are design in such way that they are zero cost when nothing is thrown. Trade of is that when something exception is thrown unwinding a stack is extremely slow (on some cpp-con someone said that it is x40 slower, I didn't measure it). This is the reason use of std::optional or std::variant instead of exception can be so beneficial.

AFAIK standard comity is working on new kind of exceptions mechanism which will behave like std::variant (similar how this is made in Swift).

您可以使用std::optional

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM