这是过于聪明还是不安全?

发布于 2024-09-02 03:01:32 字数 1400 浏览 4 评论 0原文

我最近正在编写一些代码,并决定在 C++ 中研究我的运算符重载,因为我以前从未真正实现过它。因此,我使用比较函数重载了矩阵类的比较运算符,如果 LHS 小于 RHS,则返回 0;如果 LHS 大于 RHS,则返回 1;如果它们相等,则返回 2。然后我利用了 c++ 中整数上的逻辑非属性,将所有比较放在一行中:

inline bool Matrix::operator<(Matrix &RHS){
  return ! (compare(*this,RHS));
}
inline bool Matrix::operator>(Matrix &RHS){
  return ! (compare((*this),RHS)-1);
}
inline bool Matrix::operator>=(Matrix &RHS){
  return compare((*this),RHS);
}
inline bool Matrix::operator<=(Matrix &RHS){
  return compare((*this),RHS)-1;
}
inline bool Matrix::operator!=(Matrix &RHS){
  return compare((*this),RHS)-2;
}
inline bool Matrix::operator==(Matrix &RHS){
  return !(compare((*this),RHS)-2);
}

显然我应该将 RHS 作为常量传递,我可能不会再次使用这个矩阵类,而且我没有'不想编写另一个不是引用的函数来仅为比较器操作获取数组索引值。

根据建议,这里是比较返回 -1 表示小于、0 表示相等、1 表示正数的代码。

inline bool Matrix::operator<(Matrix &RHS){
  return ! (compare(*this,RHS)+1);
}
inline bool Matrix::operator>(Matrix &RHS){
  return ! (compare((*this),RHS)-1);
}
inline bool Matrix::operator>=(Matrix &RHS){
  return compare((*this),RHS)+1;
}
inline bool Matrix::operator<=(Matrix &RHS){
  return compare((*this),RHS)-1;
}
inline bool Matrix::operator!=(Matrix &RHS){
  return compare((*this),RHS);
}
inline bool Matrix::operator==(Matrix &RHS){
  return !(compare((*this),RHS));
}

我不知道这真的会增加可读性。

I was working on some code recently and decided to work on my operator overloading in c++, because I've never really implemented it before. So I overloaded the comparison operators for my matrix class using a compare function that returned 0 if LHS was less than RHS, 1 if LHS was greater than RHS and 2 if they were equal. Then I exploited the properties of logical not in c++ on integers, to get all of my compares in one line:

inline bool Matrix::operator<(Matrix &RHS){
  return ! (compare(*this,RHS));
}
inline bool Matrix::operator>(Matrix &RHS){
  return ! (compare((*this),RHS)-1);
}
inline bool Matrix::operator>=(Matrix &RHS){
  return compare((*this),RHS);
}
inline bool Matrix::operator<=(Matrix &RHS){
  return compare((*this),RHS)-1;
}
inline bool Matrix::operator!=(Matrix &RHS){
  return compare((*this),RHS)-2;
}
inline bool Matrix::operator==(Matrix &RHS){
  return !(compare((*this),RHS)-2);
}

Obviously I should be passing RHS as a const, I'm just probably not going to use this matrix class again and I didn't feel like writing another function that wasn't a reference to get the array index values solely for the comparator operation.

As per suggestion here is the code if Compare returns -1 for less, 0 for equal and 1 for positive.

inline bool Matrix::operator<(Matrix &RHS){
  return ! (compare(*this,RHS)+1);
}
inline bool Matrix::operator>(Matrix &RHS){
  return ! (compare((*this),RHS)-1);
}
inline bool Matrix::operator>=(Matrix &RHS){
  return compare((*this),RHS)+1;
}
inline bool Matrix::operator<=(Matrix &RHS){
  return compare((*this),RHS)-1;
}
inline bool Matrix::operator!=(Matrix &RHS){
  return compare((*this),RHS);
}
inline bool Matrix::operator==(Matrix &RHS){
  return !(compare((*this),RHS));
}

I don't know that this really increases the readability though.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

暮凉 2024-09-09 03:01:32

是的,它太聪明了 - 我读了该代码,并且必须考虑为什么要从名为 compare 的函数中减去两个。别让我思考。

如果你很聪明地让你的代码适合一行,那么你的优先级就会变得混乱。您应该根据需要使用尽可能多的行以使代码尽可能清晰。

程序必须编写供人阅读,并且只是顺便供机器执行。 (Abelson 和 Sussman,计算机程序的结构和解释)

Yes, it's overly clever - I read that code and have to think about why you're subtracting two from a function called compare. Don't make me think.

If you're being clever to make your code fit on one line then you've got muddled priorities. You should use as many lines as needed to make your code as clear as possible.

Programs must be written for people to read, and only incidentally for machines to execute. (Abelson & Sussman, Structure and Interpretation of Computer Programs)

や莫失莫忘 2024-09-09 03:01:32

据我所知,它是安全的,但每个阅读代码的人都需要仔细查看。你为什么要这样做?

不管怎样,为了比较,你所需要的只是 <==!= ,其余的都是规范的,我主要写它通过肌肉记忆。此外,如果 IMO 作为非成员实现,二元运算符会平等对待其操作数(它们不会影响它们)。鉴于此,加上使用合理的比较函数(-10+1)并添加必要的const >,我得出这样的结论:

// doing real work
inline bool operator<(const Matrix& l, const Matrix &r)
{
  return -1 == compare(l,r);
}
inline bool operator==(const Matrix& l, const Matrix &r)
{
  return 0 == compare(l,r);
}
// canonical
inline bool operator> (const Matrix& l, const Matrix &r) {return r < l;}
inline bool operator>=(const Matrix& l, const Matrix &r) {return !(l < r);}
inline bool operator<=(const Matrix& l, const Matrix &r) {return !(r < l);}
inline bool operator!=(const Matrix& l, const Matrix &r) {return !(l == r);}

这些比较可能不像您的那么聪明,但是每个见过 strcmp() 的人都会立即知道它们的作用。请注意,我什至添加了 0 !=compare(...),这对于编译器来说是完全不必要的。对于人类来说,IMO 它比隐式转换为 bool 更清楚地表明发生了什么。另外,它强调了 operator< 实现的对称性。

As far as I can see it's safe, but it does take looking twice for everybody reading the code. Why would you want to do this?

Anyway, for comparison, all you ever need is < and either == or !=, the rest is canonical and I write it mostly by muscle memory. Also, binary operators treating their operands equally (they leave them alone) should IMO be implemented as non-members. Given this, plus using the sane comparison function (-1, 0, +1) and adding the necessary const, I come to this:

// doing real work
inline bool operator<(const Matrix& l, const Matrix &r)
{
  return -1 == compare(l,r);
}
inline bool operator==(const Matrix& l, const Matrix &r)
{
  return 0 == compare(l,r);
}
// canonical
inline bool operator> (const Matrix& l, const Matrix &r) {return r < l;}
inline bool operator>=(const Matrix& l, const Matrix &r) {return !(l < r);}
inline bool operator<=(const Matrix& l, const Matrix &r) {return !(r < l);}
inline bool operator!=(const Matrix& l, const Matrix &r) {return !(l == r);}

The comparisons might not be as clever as yours, but everyone who's ever seen strcmp() knows immediately what they do. Note that I even added 0 != compare(...), which is completely unnecessary - for the compiler. For humans IMO it makes it more clear what's going on than the implicit cast to bool. Plus it emphasizes the symmetry to operator<'s implementation.

眼泪也成诗 2024-09-09 03:01:32

是的,这太复杂了。

对于相等的值,compare 应返回 0;如果 this 较大,则返回正值;如果 this 较小,则返回负值。

它会简单得多并且性能均匀。

如果我要审查此代码,我会将其标记为应该修复的内容。

Yes, this is too complex.

compare should return 0 for equal values, positive if this is bigger and negative if this is smaller.

It would be much simpler and would be of even performance.

If I would given this code for review, I would mark this as something that should be fixed.

灼疼热情 2024-09-09 03:01:32

使用六个比较运算符中的任何一个将 compare 的输出与 0 进行比较将为相应的重载运算符产生正确的结果。这样,您的代码将非常具有可读性,并且可以立即看出它是正确的(如果 compare 正确实现)。

inline bool Matrix::operator < (const Matrix &RHS){
  return compare(*this, RHS) < 0;
}
inline bool Matrix::operator > (const Matrix &RHS){
  return compare(*this, RHS) > 0;
}
inline bool Matrix::operator >= (const Matrix &RHS){
  return compare(*this, RHS) >= 0;
}
inline bool Matrix::operator <= (const Matrix &RHS){
  return compare(*this, RHS) <= 0;
}
inline bool Matrix::operator != (const Matrix &RHS){
  return compare(*this, RHS) != 0;
}
inline bool Matrix::operator == (const Matrix &RHS){
  return compare(*this, RHS) == 0;
}

Comparing the output of compare to 0 using any of the six comparison operators will yield the correct result for the corresponding overloaded operator. That way your code will be very readable and it will be instantly obvious that it's correct (if compare is correctly implemented).

inline bool Matrix::operator < (const Matrix &RHS){
  return compare(*this, RHS) < 0;
}
inline bool Matrix::operator > (const Matrix &RHS){
  return compare(*this, RHS) > 0;
}
inline bool Matrix::operator >= (const Matrix &RHS){
  return compare(*this, RHS) >= 0;
}
inline bool Matrix::operator <= (const Matrix &RHS){
  return compare(*this, RHS) <= 0;
}
inline bool Matrix::operator != (const Matrix &RHS){
  return compare(*this, RHS) != 0;
}
inline bool Matrix::operator == (const Matrix &RHS){
  return compare(*this, RHS) == 0;
}
农村范ル 2024-09-09 03:01:32

如果您担心某件事是否过于聪明......它可能是:-)

If you worry whether something is overly clever ... it probably is :-)

允世 2024-09-09 03:01:32

聪明的?

警告:请参阅评论

我认为!=调用compare(它检查两个矩阵的所有值以找出哪一个更大)因为 ifm1[0][0]!=m2[0][0]then!= 可能已经返回false。所以我认为简化这些运算符的编写是一个好主意,如果性能根本不重要,那么它可以被认为是聪明的。但如果性能确实很重要,那么它就不聪明了。

安全的?

我还认为它是安全的,因为它产生了正确的结果。

Clever?

warning: please see comments

I think it is unefficient for!=to callcompare (which checks all values of both matrices in order to find out which one is bigger) because ifm1[0][0]!=m2[0][0]then!=could already returnfalse. So i think it's a nice idea to simplify writing these operators and if performance doesn't matter at all, it can be considered clever. But if performance does matter, it is not clever.

Safe?

I also think it is safe because it produces the right results.

最单纯的乌龟 2024-09-09 03:01:32

如前所述,我认为标准方法是返回 <当LHS<0时为0右轴,> 0 表示 LHS > RHS,0 表示相等。

但我可以问另一个问题吗?为什么要在这里使用运算符重载?运算符重载背后的想法是(或者应该是)能够以直观的方式使用对象。但据我所知,除了(不)相等之外,没有比较矩阵的标准定义。至少我不知道。那么当我读到M1<<时我会想到什么? M2?

让我猜一下:operator<() 和operator>() 只是为了完整性而添加的,但实际上永远不会在现实世界的代码中使用 - 对吧?如果是这样,请不要实施它们。

As mentioned before, I think the standard way would be to return < 0 when LHS < RHS, > 0 for LHS > RHS, and 0 for equality.

But may I ask another question? Why use operator overloading here at all? The idea behind operator overloading is (or should be) to be able to use objects in an intuive way. But as far as I know, there is no standard definition for comparing matrices other than for (in)equality. At least I know of none. So what shall I think of when I read M1 < M2?

Just let me guess: operator<() and operator>() were just added for completeness, but will never actually be used in real world code - right? If so, don't implement them.

方圜几里 2024-09-09 03:01:32

我会给你我自己的方法:

#include <boost/operators.hpp>

class Matrix: boost::equality_comparable<Matrix
            , boost::less_than_comparable<Matrix
              > >
{
}; // class Matrix

bool operator==(const Matrix&, const Matrix&);

bool operator<(const Matrix&, const Matrix&);

我使用的台词比你少,没有任何聪明技巧。至于升压?嗯,现在它已经相当标准了,并且有在线记录。您始终可以添加一些注释:

// boost::equality_comparable: automatically generate != from ==
// boost::less_than_comparable: automatically generate >, <=, >= from <
// search for Boost.Operators on the web to get more information

最后一句话:我不知道您正在编写的特定应用程序,但是使用矩阵我总是发现拥有一个 Matrix 基类和一些< code>TMatrix 子类(模板,如 T 所示),其维度在编译时已知。然后,您可以在 TMatrix 上提供运算符,它只能处理相似维度的矩阵,因为其他任何东西都是异端邪说,因此具有编译时诊断。

I'll give you my own way:

#include <boost/operators.hpp>

class Matrix: boost::equality_comparable<Matrix
            , boost::less_than_comparable<Matrix
              > >
{
}; // class Matrix

bool operator==(const Matrix&, const Matrix&);

bool operator<(const Matrix&, const Matrix&);

I use less lines than you do without any clever tricks. As for Boost ? Well, it's pretty standard by now and it's documented online. You can always add some comments:

// boost::equality_comparable: automatically generate != from ==
// boost::less_than_comparable: automatically generate >, <=, >= from <
// search for Boost.Operators on the web to get more information

A last word: I don't know about the particular application you are writing, but using matrices I always found it a good idea to have a Matrix base class and some TMatrix subclass (template, as the T indicates) with dimensions known at compile time. You can then provide operators on TMatrix which can only deal with matrices of similar dimensions, since anything else is heresy, and thus have compile-time diagnosis.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文