为什么C ++编译器不定义operator ==和operator!=?

本文讨论了C++编译器为何不为类自动定义比较运算符如operator==和operator!=。尽管编译器可以提供默认构造函数、复制构造函数等,但比较运算符的实现需要考虑更多细节,如深层比较和浅层比较、对象的唯一性等。开发者应根据需求自行定义这些运算符以确保正确性。
摘要由CSDN通过智能技术生成

本文翻译自:Why don't C++ compilers define operator== and operator!=?

I am a big fan of letting the compiler do as much work for you as possible. 我非常乐于让编译器为您完成尽可能多的工作。 When writing a simple class the compiler can give you the following for 'free': 编写简单的类时,编译器可以为您提供以下“免费”功能:

  • A default (empty) constructor 默认(空)构造函数
  • A copy constructor 复制构造函数
  • A destructor 析构函数
  • An assignment operator ( operator= ) 赋值运算符( operator=

But it cannot seem to give you any comparison operators - such as operator== or operator!= . 但这似乎无法为您提供任何比较运算符-例如operator==operator!= For example: 例如:

class foo
{
public:
    std::string str_;
    int n_;
};

foo f1;        // Works
foo f2(f1);    // Works
foo f3;
f3 = f2;       // Works

if (f3 == f2)  // Fails
{ }

if (f3 != f2)  // Fails
{ }

Is there a good reason for this? 是否有充分的理由呢? Why would performing a member-by-member comparison be a problem? 为什么进行逐成员比较会是一个问题? Obviously if the class allocates memory then you'd want to be careful, but for a simple class surely the compiler could do this for you? 显然,如果该类分配了内存,那么您要格外小心,但是对于一个简单的类,编译器肯定可以为您执行此操作吗?


#1楼

参考:https://stackoom.com/question/UGH/为什么C-编译器不定义operator-和operator


#2楼

I agree, for POD type classes then the compiler could do it for you. 我同意,对于POD类型类,编译器可以为您完成。 However what you might consider simple the compiler might get wrong. 但是,您可能认为简单的编译器可能会出错。 So it is better to let the programmer do it. 因此最好让程序员来做。

I did have a POD case once where two of the fields were unique - so a comparison would never be considered true. 我曾经有过一次POD案例,其中两个字段是唯一的-因此,比较永远不会被认为是正确的。 However the comparison I needed only ever compared on the payload - something the compiler would never understand or could ever figure out on it's own. 但是,我只需要在有效负载上进行比较,这是编译器永远无法理解或无法自行解决的。

Besides - they don't take long to write do they?! 此外-他们不需要花很多时间来写吗?


#3楼

The compiler wouldn't know whether you wanted a pointer comparison or a deep (internal) comparison. 编译器不会知道您要进行指针比较还是深度(内部)比较。

It's safer to just not implement it and let the programmer do that themselves. 只执行而不让程序员自己做是比较安全的。 Then they can make all the assumptions they like. 然后他们可以做出所有喜欢的假设。


#4楼

C++0x has had a proposal for default functions, so you could say default operator==; 的C ++ 0x 默认功能的建议,所以你可以说default operator==; We've learnt that it helps to make these things explicit. 我们了解到,使这些事情变得清晰起来是有帮助的。


#5楼

Conceptually it is not easy to define equality. 从概念上讲,定义平等并不容易。 Even for POD data, one could argue that even if the fields are the same, but it is a different object (at a different address) it is not necessarily equal. 即使对于POD数据,也可能会争辩说,即使字段相同,但它是一个不同的对象(位于不同的地址),也不一定相等。 This actually depends on the usage of the operator. 这实际上取决于操作员的用法。 Unfortunately your compiler is not psychic and cannot infer that. 不幸的是,您的编译器并不灵敏,因此无法进行推断。

Besides this, default functions are excellent ways to shoot oneself in the foot. 除此之外,默认功能是脚踩自己的好方法。 The defaults you describe are basically there to keep compatibility with POD structs. 您描述的默认值基本上可以保证与POD结构的兼容性。 They do however cause more than enough havoc with developers forgetting about them, or the semantics of the default implementations. 但是,它们的确给开发人员造成了极大的破坏,使他们忘记了它们或默认实现的语义。


#6楼

It is not possible to define default == , but you can define default != via == which you usually should define yourselves. 不可能定义default == ,但是可以通过==定义默认!= ,通常应该自己定义。 For this you should do following things: 为此,您应该执行以下操作:

#include <utility>
using namespace std::rel_ops;
...

class FooClass
{
public:
  bool operator== (const FooClass& other) const {
  // ...
  }
};

You can see http://www.cplusplus.com/reference/std/utility/rel_ops/ for details. 有关详细信息,请参见http://www.cplusplus.com/reference/std/utility/rel_ops/

In addition if you define operator< , operators for <=, >, >= can be deduced from it when using std::rel_ops . 另外,如果定义operator< ,则可以在使用std::rel_ops时从中推导出<=,>,> =的运算符。

But you should be careful when you use std::rel_ops because comparison operators can be deduced for the types you are not expected for. 但是,在使用std::rel_ops时应格外小心,因为可以推导比较运算符来表示不需要的类型。

More preferred way to deduce related operator from basic one is to use boost::operators . 从基础推论出相关运算符的更优选方法是使用boost :: operators

The approach used in boost is better because it define the usage of operator for the class you only want, not for all classes in scope. boost中使用的方法更好,因为它为您只想要的类而不是作用域中的所有类定义了运算符的用法。

You can also generate "+" from "+=", - from "-=", etc... (see full list here ) 您还可以从“ + =”生成“ +”,从-=生成-,等等...( 在此处查看完整列表)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值