为什么C ++编译器不定义运算符==和运算符!=?
我非常喜欢让编译器尽可能为您做很多工作。 当编写一个简单的类时,编译器可以为你提供以下'免费':
operator=
) 但它似乎无法给你任何比较运算符 - 比如operator==
或operator!=
。 例如:
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
{ }
这是否有很好的理由? 为什么执行逐个成员的比较会成为问题? 很明显,如果类需要分配内存,那么你应该小心,但是对于一个简单的类,编译器肯定会为你做这件事?
编译器不知道你是想要一个指针比较还是深入的(内部)比较。
只是没有实现它并让程序员自己去做就更安全了。 然后他们可以做出他们喜欢的所有假设。
有说法认为如果编译器可以提供默认的拷贝构造函数,它应该能够提供类似的默认operator==()
会产生一定的意义。 我认为决定不为该运算符提供编译器生成的缺省值的原因可以由Stroustrup关于“C ++的设计和演化”中的默认拷贝构造函数的说法来猜测(第11.4.1节 - 复制的控制) :
我个人认为不幸的是复制操作是默认定义的,我禁止复制许多课程的对象。 但是,C ++从C继承了它的默认赋值和拷贝构造函数,并且它们经常被使用。
因此,而不是“为什么不C ++有一个默认的operator==()
?”,问题应该是“为什么C ++有一个默认的赋值和复制构造函数?”,答案是这些项目被包括在勉强Stroustrup向后兼容C(可能是大多数C ++的瑕疵的原因,但也可能是C ++普及的主要原因)。
出于我自己的目的,在我的IDE中,我用于新类的代码段包含一个私有赋值运算符和复制构造函数的声明,这样当创建一个新类时,我不会获得默认赋值和复制操作 - 我必须显式删除声明如果我希望编译器能够为我生成这些操作,请从private:
部分执行这些操作。
更新2:不幸的是,这个提议并没有使它成为C ++ 17,所以现在在这方面没有任何改变。
更新:当前版本的提案有很高的机会投票到C ++ 17在这里。
最近有一个关于明确违约的比较运算符的提案(N4126),它得到了标准委员会的非常积极的反馈,所以希望我们能以某种形式在C ++ 17中看到它。
简言之,建议的语法是:
struct Thing
{
int a, b, c;
std::string d;
};
bool operator==(const Thing &, const Thing &)= default;
bool operator!=(const Thing &, const Thing &)= default;
或者以私人领域的课程的friend
形式:
class Thing
{
int a, b;
friend bool operator<(Thing, Thing) = default;
friend bool operator>(Thing, Thing) = default;
friend bool operator<=(Thing, Thing) = default;
friend bool operator>=(Thing, Thing) = default;
};
甚至简而言之:
struct Thing
{
int a, b, c;
std::string d;
default: ==, !=, <, >, <=, >=; // defines the six non-member functions
};
当然,在这个提案最终被接受之前,所有这些都可能会改变。
链接地址: http://www.djcxy.com/p/2025.html上一篇: Why don't C++ compilers define operator== and operator!=?