C++ 为什么赋值运算符和相等运算符之间没有1:1关系?

C++ 为什么赋值运算符和相等运算符之间没有1:1关系?,c++,operator-overloading,assignment-operator,equality-operator,C++,Operator Overloading,Assignment Operator,Equality Operator,在下面的代码示例中,因为我比较了两个std::map对象,所以我不得不实现MyId::operator==() MyId是一个简单的类:基本上是数组上的包装器。这让我想知道为什么强制使用相等运算符:为什么不给我们一个默认的按位比较器?毕竟,我们得到了一个默认赋值运算符,它在对象之间进行按位成员复制 我理解深拷贝和浅拷贝之间的区别以及赋值运算符和相等运算符的需要。我的问题是,当存在默认赋值时,为什么没有默认的“位相等检查” #include <iostream> #include &l

在下面的代码示例中,因为我比较了两个
std::map
对象,所以我不得不实现
MyId::operator==()

MyId
是一个简单的类:基本上是数组上的包装器。这让我想知道为什么强制使用相等运算符:为什么不给我们一个默认的按位比较器?毕竟,我们得到了一个默认赋值运算符,它在对象之间进行按位成员复制

我理解深拷贝和浅拷贝之间的区别以及赋值运算符和相等运算符的需要。我的问题是,当存在默认赋值时,为什么没有默认的“位相等检查”

#include <iostream>
#include <map>
#include <cstring>

typedef int myid[ 3 ];

struct MyId
{
  myid id_;
  bool operator<( const struct MyId& other ) const { return this < &other; }
  bool operator==( const struct MyId& other ) const
  {
    return ( 0 == std::memcmp( id_, other.id_, sizeof( myid ) ));
  }
};

int main( int argc, char* argv[] )
{
  std::map< MyId, int> map;
  MyId id = { 1, 2, 3 };
  map[ id ] = 5;

  std::map< MyId, int> map2;
  map2[ id ] = 5;

  // This forces implementation of MyId::operator==():
  std::cout << std::boolalpha <<( map == map2 ) << std::endl;

  MyId i1 = { 4, 5, 6 };
  MyId i2 = { 7, 8, 9 };

  // No required implementation of MyId::operator=():
  i1 = i2;

  return 0;
}
#包括
#包括
#包括
typedef int myid[3];
结构MyId
{
粘虫;
布尔算子映射;
MyId={1,2,3};
map[id]=5;
std::mapmap2;
map2[id]=5;
//这将强制实现MyId::operator==():
标准::cout
毕竟,我们得到了一个默认赋值运算符,它执行
对象之间的按位复制


不,不是。相反,默认的复制分配运算符的构造方式是复制分配对象的每个成员。根据复制分配运算符在字段类型中的实现方式,结果可能远不止是按位复制

无论如何,默认的复制指定(或复制构造、移动指定,甚至销毁)行为的设计符合常见的基本需求。基于语言规范,它在大多数情况下都是可用的,但在某些已知情况下,语言对您的语义不确定,并且需要明确的定义


相等运算符是不同的。实际的相等关系不是由语言语法暗示的,而是纯粹由语义暗示的。编译器不知道如何看到类“相等”的两个实例,因此它要求您告诉他。

赋值运算符和复制构造函数执行成员复制,而不是按位复制。“默认复制分配运算符的构造方式为复制分配对象的每个成员"你说得对。我的大脑放屁。@StoneThrow我的意思不是要指出你的错误,但我实际上是在回答你的问题:)@iehrlick明白,我只是不好意思在我发布问题时忘记了这一点。:)所以我想你总是可以免费获得任务,因为默认的实现是一个memberwise copy、 任何类最终都是POD的集合,POD显然具有内置赋值。因此,对象之间的副本将递归地进行成员复制,直到达到POD副本。那么,这只是一个设计决策吗?同样的,不能实现相等?看起来可能是这样。@StoneThrow语言设计人员(与编译器开发人员一起)讨厌复杂性,他们尽可能避免复杂性。在某些OO语言的某些实现中,引入默认比较运算符在技术上可能是可行的……但这是一个现实。如何默认比较没有任何字段的类的两个对象?如何默认比较单个ba的不同派生类的两个对象SE类-通过它们的基引用?应该<代码>可变的字段比较吗?等等。这会带来一个非常好的大的复杂性,C++本身就充满了复杂性。