在工作中,我最近为从已发布的规范实现的类编写了一个小于运算符,该类具有许多属性,其中六个用于唯一标识类的实例。 (为了这个问题,我们将这些属性称为a-f。)此外,这六个属性有六种不同的类型。我将运算符定义为:
class Shape { void draw() {}}
class Circle extends Shape {void draw() {}}
class Square extends Shape {void draw() {}}
class Rectangle extends Shape {void draw() {}}
public class Test {
/*
* Example for an upper bound wildcard (Get values i.e Producer `extends`)
*
* */
public void testCoVariance(List<? extends Shape> list) {
list.add(new Shape()); // Error: is not applicable for the arguments (Shape) i.e. inheritance is not supporting
list.add(new Circle()); // Error: is not applicable for the arguments (Circle) i.e. inheritance is not supporting
list.add(new Square()); // Error: is not applicable for the arguments (Square) i.e. inheritance is not supporting
list.add(new Rectangle()); // Error: is not applicable for the arguments (Rectangle) i.e. inheritance is not supporting
Shape shape= list.get(0);//compiles so list act as produces only
/*You can't add a Shape,Circle,Square,Rectangle to a List<? extends Shape>
* You can get an object and know that it will be an Shape
*/
}
/*
* Example for a lower bound wildcard (Put values i.e Consumer`super`)
* */
public void testContraVariance(List<? super Shape> list) {
list.add(new Shape());//compiles i.e. inheritance is supporting
list.add(new Circle());//compiles i.e. inheritance is supporting
list.add(new Square());//compiles i.e. inheritance is supporting
list.add(new Rectangle());//compiles i.e. inheritance is supporting
Shape shape= list.get(0); // Error: Type mismatch, so list acts only as consumer
Object object= list.get(0); // gets an object, but we don't know what kind of Object it is.
/*You can add a Shape,Circle,Square,Rectangle to a List<? super Shape>
* You can't get an Shape(but can get Object) and don't know what kind of Shape it is.
*/
}
}
这当然打破了Linux内核编码的理念,#34;如果你需要超过3级的缩进,你还是要搞砸了,应该修复你的程序。&#34;所以我的问题是,是否有更好的方法来定义此运算符,以便没有这么多级别的缩进?
答案 0 :(得分:11)
你可以写这样的词典比较:
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;
您可以使用以下单一回执重写此内容:
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 :(得分:11)
您可以使用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);
}
答案 2 :(得分:2)
由于您只设置了retval
1次并在设置后返回,因此您可以将其完全删除并改为使用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...
}
答案 3 :(得分:2)
这是一个格式正确的嵌套三元语句。这也是执行语句的单行。
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.
答案 4 :(得分:1)
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;