我可以避免超过 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.
在工作中,我最近为根据已发布规范实现的 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.