在C ++中比较结构时找不到==运算符

| 比较以下结构的两个实例,我收到一个错误:
struct MyStruct1 {
    MyStruct1(const MyStruct2 &_my_struct_2, const int _an_int = -1) :
        my_struct_2(_my_struct_2),
        an_int(_an_int)
    {}

    std::string toString() const;

    MyStruct2 my_struct_2;
    int an_int;
};
错误是:   错误C2678:二进制\'== \':无运算符   发现需要左手操作数   \'myproj :: MyStruct1 \'类型的(或那里   是不可接受的转换) 为什么?     
已邀请:
在C ++中,默认情况下,
struct
没有比较运算符。您需要编写自己的:
bool operator==(const MyStruct1& lhs, const MyStruct1& rhs)
{
    return /* your comparison code goes here */
}
    
正如其他人所说,您需要自己实现比较功能。 有一种建议的方法可以要求编译器生成明显/ naive(?)实现:请参见此处。 尚未对此进行标准化可能对C ++似乎无济于事,但结构/类通常具有一些要从比较中排除的数据成员(例如,计数器,缓存的结果,容器容量,上次操作成功/错误代码,游标),以及作为做出各种事情的决定,包括但不限于: 首先比较哪些字段,例如比较特定的
int
成员可能会很快消除99%的不相等对象,而ѭ4often成员可能经常具有相同的条目,并且比较起来比较昂贵-如果在运行时加载值,程序员可能会洞悉编译器无法可能 比较字符串时:区分大小写,空格和分隔符的等效性,转义约定... 比较浮点/双精度时的精度 NaN浮点值是否应视为相等 比较指针或指向数据(如果是后者,则如何知道指针是否指向数组以及需要比较多少对象/字节) 比较未排序的容器(例如
vector
list
)时,顺序是否重要?如果是,在比较之前就可以对它们进行就地排序与每次比较时使用额外的内存对临时对象进行排序是否可以 当前有多少个数组元素包含应该比较的有效值(某处是否有大小或前哨?) 比较
union
的哪个成员 归一化:例如,日期类型可能允许超出范围的日期或月份,或者有理/分数对象可能有6/8的空间,而另一个对象有3/4的空间,出于性能原因,它们可以纠正懒惰地进行单独的标准化步骤;您可能需要决定是否在比较之前触发标准化 弱指针无效时该怎么办 如何处理本身未实现ѭ8的成员和基础(但可能具有
compare()
operator<
str()
或吸气剂...) 在读取/比较其他线程可能想要更新的数据时必须采取什么锁 因此,在您明确考虑比较对于您的特定结构意味着什么之前,最好先出错,而不是让其编译但在运行时没有给您有意义的结果。 综上所述,如果C ++让您确定“天真”的逐个成员
==
测试是可以的,那么最好让您说ѭ12be。
!=
也一样。给定多个成员/库,\“ default \”
<
<=
>
>=
实现似乎没有希望-基于声明顺序的级联是可能的,但鉴于冲突的必要性,这不太可能是想要的用于成员订购(基础必须在成员之前,必须按可访问性分组,在依赖使用之前进行构造/破坏)。为了更广泛地发挥作用,C ++将需要一个新的数据成员/基础注释系统来指导选择-尽管在标准中这将是一件很了不起的事情,理想情况下是与基于AST的用户定义代码生成结合在一起...它会发生一天。 等式运算符的典型实现 合理的实施 合理而有效的实现方式可能是:
inline bool operator==(const MyStruct1& lhs, const MyStruct1& rhs)
{
    return lhs.my_struct2 == rhs.my_struct2 &&
           lhs.an_int     == rhs.an_int;
}
注意,这也需要needs21ѭ的
operator==
。 在下面的“ MyStruct1的详细信息的讨论”标题下讨论了此实现的含义和替代方法。 对==,<,> <=等的一致方法 利用
std::tuple
的比较运算符比较您自己的类实例很容易-只需使用
std::tie
即可按所需的比较顺序创建对字段的引用元组。从这里概括我的例子:
inline bool operator==(const MyStruct1& lhs, const MyStruct1& rhs)
{
    return std::tie(lhs.my_struct2, lhs.an_int) ==
           std::tie(rhs.my_struct2, rhs.an_int);
}

inline bool operator<(const MyStruct1& lhs, const MyStruct1& rhs)
{
    return std::tie(lhs.my_struct2, lhs.an_int) <
           std::tie(rhs.my_struct2, rhs.an_int);
}

// ...etc...
当您“拥有”(即可以编辑公司和第三方库的一个因子)要比较的类时,尤其是C ++ 14准备从to25ѭ语句推论函数返回类型时,它将通常最好将一个“ tie”成员函数添加到您想要比较的类中:
auto tie() const { return std::tie(my_struct1, an_int); }
然后,以上比较简化为:
inline bool operator==(const MyStruct1& lhs, const MyStruct1& rhs)
{
    return lhs.tie() == rhs.tie();
}
如果您需要比较比较完整的运算符,建议使用升压运算符(搜索search28ѭ)。如果由于某种原因不合适,则可能会(或可能会)不喜欢支持宏(在线)的想法:
#define TIED_OP(STRUCT, OP, GET_FIELDS) \\
    inline bool operator OP(const STRUCT& lhs, const STRUCT& rhs) \\
    { \\
        return std::tie(GET_FIELDS(lhs)) OP std::tie(GET_FIELDS(rhs)); \\
    }

#define TIED_COMPARISONS(STRUCT, GET_FIELDS) \\
    TIED_OP(STRUCT, ==, GET_FIELDS) \\
    TIED_OP(STRUCT, !=, GET_FIELDS) \\
    TIED_OP(STRUCT, <, GET_FIELDS) \\
    TIED_OP(STRUCT, <=, GET_FIELDS) \\
    TIED_OP(STRUCT, >=, GET_FIELDS) \\
    TIED_OP(STRUCT, >, GET_FIELDS)
...然后可以使用...
#define MY_STRUCT_FIELDS(X) X.my_struct2, X.an_int
TIED_COMPARISONS(MyStruct1, MY_STRUCT_FIELDS)
(此处为C ++ 14成员关系版本) 讨论MyStruct1的细节 选择提供独立于成员ѭ31的成员还是有隐忧的... 独立实施 您有一个有趣的决定。由于您的班级可以由
MyStruct2
隐式构造,因此独立/非成员
bool operator==(const MyStruct2& lhs, const MyStruct2& rhs)
函数将支持...
my_MyStruct2 == my_MyStruct1
...首先从
my_myStruct2
创建一个临时
MyStruct1
,然后进行比较。肯定会将ѭ37设置为构造函数的默认参数值
-1
。根据您在
operator==
的实现中是否包含
an_int
比较,a35ѭ可能等于或不等于
MyStruct2
,而
MyStruct2
本身等于
MyStruct1
\的
my_struct_2
成员!此外,创建临时ѭ35可能是非常低效的操作,因为它涉及将现有的
my_struct2
成员复制到临时中,只是在比较之后将其丢弃。 (当然,您可以通过使构造函数
explicit
或删除
an_int
的默认值来防止implicit35的这种隐式构造以进行比较。) 会员实施 如果要避免从ѭ21隐式构造
MyStruct1
,请将比较运算符设为成员函数:
struct MyStruct1
{
    ...
    bool operator==(const MyStruct1& rhs) const
    {
        return tie() == rhs.tie(); // or another approach as above
    }
};
请注意,
const
关键字(仅对于成员实现而言才需要),建议编译器比较对象不会对其进行修改,因此可以在
const
对象上使用。 比较可见的表示 有时,获得所需比较的最简单方法是...
    return lhs.to_string() == rhs.to_string();
...这通常也非常昂贵-ѭ56的痛苦创建只是被扔掉了!对于具有浮点值的类型,比较可见表示表示显示位数的数量确定了比较期间将近似等于的值视为相等的容差。     
您需要为
MyStruct1
明确定义ѭ5​​7ѭ。
struct MyStruct1 {
  bool operator == (const MyStruct1 &rhs) const
  { /* your logic for comparision between \"*this\" and \"rhs\" */ }
};
现在==比较对于2个这样的对象是合法的。     
从C ++ 20开始,应该有可能通过声明默认的三向比较运算符(\“ spaceship \”运算符)来向类添加全套默认比较运算符(
==
<=
等)。这个:
struct Point {
    int x;
    int y;
    auto operator<=>(const Point&) const = default;
};
使用兼容的C ++ 20编译器,假设MyStruct2的定义兼容,则将该行添加到MyStruct1和MyStruct2可能足以进行相等比较。     
比较不适用于C或C ++中的结构。按字段比较。     
默认情况下,结构没有
==
运算符。您必须编写自己的实现:
bool MyStruct1::operator==(const MyStruct1 &other) const {
    ...  // Compare the values, and return a bool result.
  }
    
开箱即用的==运算符仅适用于基元。为了使代码正常工作,您需要为结构重载==运算符。     
因为您没有为结构编写比较运算符。编译器不会为您生成它,因此,如果要比较,则必须自己编写。     

要回复问题请先登录注册