检查结果时减少if语句

时间:2014-05-28 09:09:46

标签: c++ if-statement

我的C ++函数有许多if语句检查被调用函数的返回值:

Result func(...){

   if (SUCCESS != func1(...))
      return ERROR;

   // do something

   if ( SUCCESS != func2(...))
      return ERROR;

   // do something else

   if (SUCCESS != func3(...))
      return ERROR;

    // do something
   .
   .
   .

}

是否有消除或减少if语句? 例如,我想要这样的东西:

Result func(...){

   Result result = SUCCESS;
   when (result != SUCCESS) return ERROR;
   result = func1(...);
   // do something
   result = func2(...);
   // do something else
   result = func3(...);
   // do something
   .
   .
   .

}

4 个答案:

答案 0 :(得分:3)

我无法帮助自己,但编写可能被视为过度工程的解决方案,但它允许为所有结果准备单个模板类(供将来使用),然后最小化代码以供实际使用(无需使用检查方法或者宏,除了这个单独的结果持有者模板类之外,不需要编写自己的包装器)。享受:D。

#include <iostream>

template<class T>
class Result
{
public:

    Result() :
        m_value(),
        m_badValue()
    {

    }

    Result(const T& value, const T& badValue) :
        m_value(value),
        m_badValue(badValue)
    {

    }

    void operator=(const T& value)
    {
        if(value == m_badValue)
        {
            throw "Bad Value!";
        }
        else
        {
            m_value = value;
        }
    }

    operator const T&() const
    {
        return m_value;
    }

    const T& value() const
    {
        return m_value;
    }

private:

    T m_value;
    T m_badValue;
};

static const int SUCCESS = 0;
static const int FAIL = -1;

int func1()
{
    return SUCCESS;
}

int func2()
{
    return SUCCESS;
}

int func3()
{
    return FAIL;
}

int main()
{
    Result<int> result(FAIL, FAIL);

    try
    {
        result = func1();
        result = func2();
        result = func3();
    }
    catch (const char *error)
    {
        ::std::cout << "Error: " << error << ::std::endl;
    }

    ::std::cout << "Last value: " << static_cast<int>(result) << " - " <<
        ((result == SUCCESS) ? "SUCCESS" : "FAIL") << ::std::endl;
}

注意:你应该只抛出::std::exception派生的内容,但我使用const char*来简化事情并准备工作示例。

答案 1 :(得分:2)

简答:没有

答案很长:不,那就是你在我所知道的每种结构化编程语言中都是这样做的。

替代方案:如果涉及的所有功能(func1func2func3)都会抛出异常而不是返回状态代码,那么您就不必使用ifs。您的函数func只会传播从其中抛出的任何异常。

编辑,扩展Tony的评论:

备选方案#2:涉及的函数不会抛出异常,但是你的函数可以。假设你有一个这样的辅助函数:

void CheckResult(Result result)
{
    if (result != SUCCESS)
        throw SomeException(result);
}

您的功能将如下所示:

void func(...)
{
    CheckResult(func1(...));
    // do something
    CheckResult(func2(...));
    // do something else
    CheckResult(func3(...));
    // do something
}

因此,if不会被避免,而是转移到另一个函数,这样你的函数就没有了。

答案 2 :(得分:2)

由于您使用C ++进行编码,而不是使用C编写,因此可以使用抛出异常的选项。使代码看起来更好,同时适当地响应异常情况是该功能背后的主要驱动力。

在使用不提供异常的第三方API的情况下,您可以将其函数包装到抛出异常的函数中,如下所示:

void func1w(...) {
    if (SUCCESS!=func1(...)) throw my_exception();
}
void func2w(...) {
    if (SUCCESS!=func2(...)) throw my_exception();
}
...
void caller() {
    try {
        func1w();
        func2w();
        func3w();
    } catch (my_exception& e) {
        cerr << "Error!" << endl;
    }
}

请注意,调用异常抛出包装器的函数可能远离完全检查异常代码,让更高级别的函数处理它们。有例外的一般规则是代码不应该捕获异常,除非它知道如何处理它们。

您还可以定义宏:

#define MUST_SUCCEED(x) if(SUCCESS!=(x))return ERROR

这是以降低可读性为代价的,因为您的代码的读者不会立即熟悉该宏:

MUST_SUCCEED(func1(...));
MUST_SUCCEED(func2(...));
MUST_SUCCEED(func3(...));

答案 3 :(得分:0)

你可以创建一个包含func1(),func2()等函数指针的向量,然后通过for循环遍历这个向量中的所有元素,调用每个函数并比较返回的值与SUCCESS。然后,如果任何函数的返回值不等于SUCCESS,则可以将标志设置为指示错误的值(在您的示例中,此标志将是名称&#39; result&#39;)。