我可以避免超过 3 个级别的缩进吗?

Could I have avoided more than 3 levels of indentation?

在工作中,我最近为根据已发布规范实现的 class 编写了一个小于运算符,它具有许多属性,其中六个用于唯一标识 class 的实例。 (为了这个问题,我们将这些属性称为 a-f。)此外,这六个属性属于六种不同类型。我这样定义运算符:

bool operator<(const Class& lhs, const Class& rhs)
{
    bool retval = (&lhs != &rhs);
    if (retval == true)
    {
        if (lhs.a == rhs.a)
        {
            if (lhs.b == rhs.b)
            {
                if (lhs.c == rhs.c)
                {
                    if (lhs.d == rhs.d)
                    {
                        if (lhs.e == rhs.e)
                        {
                            retval = (lhs.f < rhs.f);
                        } else {
                            retval = (lhs.e < rhs.e);
                        }
                    } else {
                        retval = (lhs.d < rhs.d);
                    }
                } else {
                    retval = (lhs.c < rhs.c);
                }
            } else {
                retval = (lhs.b < rhs.b);
            }
        } else {
            retval = (lhs.a < rhs.a);
        }
    }
    return retval;
}

这当然打破了 Linux 的内核编码哲学,"If you need more than 3 levels of indentation, you're screwed anyway, and should fix your program." 所以我的问题是,有没有更好的方法来定义这个运算符没有那么多级别的缩进?

这种字典序比较可以这样写:

if (lhs.a != rhs.a) return lhs.a < rhs.a;
if (lhs.b != rhs.b) return lhs.b < rhs.b;
if (lhs.c != rhs.c) return lhs.c < rhs.c;
if (lhs.d != rhs.d) return lhs.d < rhs.d;
if (lhs.e != rhs.e) return lhs.e < rhs.e;
return lhs.f < rhs.f;

您可以像这样用一个 return 重写它:

bool result;
if (lhs.a != rhs.a) result = lhs.a < rhs.a;
else if (lhs.b != rhs.b) result = lhs.b < rhs.b;
else if (lhs.c != rhs.c) result = lhs.c < rhs.c;
else if (lhs.d != rhs.d) result = lhs.d < rhs.d;
else if (lhs.e != rhs.e) result = lhs.e < rhs.e;
else result = lhs.f < rhs.f;
return result;

因为你只设置了1次retval,设置后return,你完全可以去掉它,改用return。那,除了重新排序你的逻辑可能看起来像:

bool operator<(const Class& lhs, const Class& rhs)
{
    if(&lhs == &rhs)
        return false;

    if (lhs.a != rhs.a)
        return (lhs.a < rhs.a);

    if (lhs.b != rhs.b)
        return (lhs.b < rhs.b);

    // And so on...
}

您可以使用std::tie进行字典序比较:

bool operator<(const Class& lhs, const Class& r) {
  return std::tie(lhs.a, lhs.b, lhs.c, lhs.d, lhs.e) < std::tie(rhs.a, rhs.b, rhs.c, rhs.d, rhs.e);
} 
if (lhs.a != rhs.a) retval = lhs.a < rhs.a; goto end;
if (lhs.b != rhs.b) retval = lhs.b < rhs.b; goto end;
if (lhs.c != rhs.c) retval = lhs.c < rhs.c; goto end;
if (lhs.d != rhs.d) retval = lhs.d < rhs.d; goto end;
if (lhs.e != rhs.e) retval = lhs.e < rhs.e; goto end;
retval = lhs.f < rhs.f
end:
return retval;

这是一个格式正确的嵌套三元语句。这也是一行执行语句。

bool operator<( const Class& lhs, const Class& rhs ) const {
    return   lhs.a != rhs.a ? lhs.a < rhs.a
           : lhs.b != rhs.b ? lhs.b < rhs.b
           : lhs.c != rhs.c ? lhs.c < rhs.c
           : lhs.d != rhs.d ? lhs.d < rhs.d
           : lhs.e != rhs.e ? lhs.e < rhs.e
           : lhs.f < rhs.f;
}

// The Above Is The Same As:
bool operator<( const class& lhs, const Class&rhs ) const {
    bool result;
    if (lhs.a != rhs.a) result = lhs.a < rhs.a;
    else if (lhs.b != rhs.b) result = lhs.b < rhs.b;
    else if (lhs.c != rhs.c) result = lhs.c < rhs.c;
    else if (lhs.d != rhs.d) result = lhs.d < rhs.d;
    else if (lhs.e != rhs.e) result = lhs.e < rhs.e;
    else result = lhs.f < rhs.f;
    return result;
}
// The Main Difference Is You Are Not Declaring A Stack Variable To The Compiler
// Nor Are You Using If Else Statements, This Is Handled Automatically By The Compiler
// And This Is Usually Done Within The Registers.