在 C++ 中返回错误代码的正确方法是什么

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3157098/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 12:13:35  来源:igfitidea点击:

Whats the right approach to return error codes in C++

c++

提问by Jeet

I'm using error codes for handling errors in my c++ project. The problem is how to return error codes from a function which is supposed to return some variable/object.

我正在使用错误代码来处理我的 C++ 项目中的错误。问题是如何从应该返回一些变量/对象的函数中返回错误代码。

consider this:

考虑一下:

long val = myobject.doSomething();

Here, myobject is an object of some class. If doSomething function encounters some error condition then how should it notify the caller (Without using exceptions).

这里,myobject 是某个类的对象。如果 doSomething 函数遇到一些错误情况,那么它应该如何通知调用者(不使用异常)。

Possible solutions:

可能的解决方案:

  1. Have a data member (say err_) in the class which can be checked by the caller. But it would be unsafe in a multi-threaded application sharing the same object and calling the same function.
  2. Use some global error variable, again same issue in a multi-threaded environment.
  1. 在类中有一个数据成员(比如 err_),调用者可以检查它。但在共享相同对象并调用相同函数的多线程应用程序中,这将是不安全的。
  2. 使用一些全局错误变量,在多线程环境中也是同样的问题。

Now how can I notify the caller about some error condition?

现在我如何通知调用者一些错误情况?

采纳答案by anthares

You can pass variable as reference and return error code in it.

您可以将变量作为引用传递并在其中返回错误代码。

回答by JUST MY correct OPINION

Make a template called, say, Maybethat it parametrized by your return value type. Whenever you return a value, wrap it in this template like this:

制作一个模板,例如,Maybe它由您的返回值类型参数化。每当你返回一个值时,把它包装在这个模板中,如下所示:

Maybe<long> result = object.somemethod();

The Maybetemplate would have a way of being instantiated with an error code (probably a static method):

Maybe模板将有一个错误代码(可能是一个静态方法)实例化的方式:

return Maybe<long>::error(code);

But ordinarily would just be returned with the value:

但通常只会返回值:

Maybe<long> retval;
retval = 15;
return retval;

(You would have to, of course, override the appropriate constructors, assignment operators, etc.)

(当然,您必须覆盖适当的构造函数、赋值运算符等。)

In the client side you call a method to check for the error.

在客户端,您调用一个方法来检查错误。

Maybe<long> result = object.somemethod();
if (result.is_error) 
{ 
    ... handle the error ...
}
else
{
    ... use the result ...
}

Again you'd need the appropriate operators defined to use Maybe<long>wherever there's a longrequired.

同样,您需要定义适当的运算符以Maybe<long>在需要的地方使用long

This sounds like a lot of work, but really the work is done once in making a good, bulletproof Maybetemplate. You'll also have to do some performance tuning on it to avoid nasty overheads. If you want to make it more flexible you can parametrize it on both the return value type and the error type. (This is only a minor increase in complexity.)

这听起来像很多工作,但实际上在制作一个好的、防弹的Maybe模板方面工作一次就完成了。您还必须对其进行一些性能调整以避免令人讨厌的开销。如果你想让它更灵活,你可以在返回值类型和错误类型上对其进行参数化。(这只是稍微增加了复杂性。)

回答by Christopher Smith

You probably want something like Alexandresu's Expected<T> idiom.

您可能想要像 Alexandresu's Expected<T> idiom 之类的东西。

回答by Mark Ransom

You can return a std::pairholding both an error code (or error object) and the desired return object. The object of interest needs a default constructor or value so you can return something even when an error is encountered.

您可以返回一个std::pair包含错误代码(或错误对象)和所需返回对象的对象。感兴趣的对象需要一个默认的构造函数或值,这样即使遇到错误也可以返回一些东西。

回答by iM71

I see there are many nice solutions, but I approach it in another way if I have this situation.

我看到有很多不错的解决方案,但如果我遇到这种情况,我会以另一种方式解决它。

auto doSomething()
{        
    // calculations
    return std::make_pair(error_code, value)
}

int main()
{
    auto result = doSomething();
    if (!result.first)
    {
        std::cout << result.second;
    }
    else
    {
        std::cout << "Something went wrong: " << result.second;
    }
}

For me it's a clean solution than passing bool as reference. autoreturn type deduction is supported from c++14

对我来说,这是一个干净的解决方案,而不是将 bool 作为参考传递。autoC++14 支持返回类型推导

回答by C. Ross

It is common to return a return/error code, and make available a property or member with the results.

通常会返回返回/错误代码,并使带有结果的属性或成员可用。

int retCode = myobject.doSomething();
if (retCode < 0){ //Or whatever you error convention is
   //Do error handling
}else{
   long val = myobject.result;
}

It is also common to pass in a pointer that is set to the return value, and return the return/error code. (See HrQueryAllRows).

传入一个设置为返回值的指针,并返回返回/错误代码也是很常见的。(请参阅HrQueryAllRows)。

long val = INIT_VAL;
int retCode = myObject.doSomething(&val);

if (retCode < 0){
    //Do error handling
}else{
    //Do something with val...
}

回答by Conor

You have three options:

您有三个选择:

  • Create a class containing the return value and a possible error code.

  • Use something like boost::optionalfor the return value, which allows for invalid responses.

  • Pass a reference to a variable and return any possible error code within that.

  • 创建一个包含返回值和可能的错误代码的类。

  • 使用类似boost::optional的返回值,允许无效响应。

  • 传递对变量的引用并返回其中的任何可能的错误代码。

回答by adf88

The most common practice is to return the error code

最常见的做法是返回错误码

long result;
int error = some_obj.SomeMethod(&result);

or return a value that indicate there was an error:

或返回一个表明有错误的值:

long result = some_obj.SomeMethod();
if (result < 0) error = some_obj.GetError();

回答by swegi

You can use exceptions.

您可以使用异常。

回答by Artyom

I would suggest following:

我建议如下:

class foo {
public:
    long doSomething();
    long doSomething(error_code &e);
};

Where error_codeis some type that holds error. It may be integer or better something based on boost::system::error_code.

error_code某种类型的错误在哪里。它可能是整数或基于 的更好的东西boost::system::error_code

And you supply two functions:

你提供两个功能:

  1. First version throws the error, for example throw boost::system::system_errorthat is created from boost::system::error_code.
  2. Second returns the error code into e.
  1. 第一个版本抛出错误,例如 throwboost::system::system_error是从boost::system::error_code.
  2. Second 将错误代码返回到 e 中。