c++20 向量比较奇怪的行为

问题描述 投票:0回答:1

为自定义类重载

operator bool()
T
会破坏
vector<T>
比较运算符。

以下代码在第一个在线编译器上尝试过,谷歌建议我打印

v1 > v2: 0
v1 < v2: 1

operator bool()
被评论并且

v1 > v2: 0
v1 < v2: 0

当它未被注释时。

#include <iostream>
#include <vector>

class T {
    int _value;
public:
    constexpr T(int value) : _value(value) {}
    constexpr bool operator==(const T rhs) const { return _value == rhs._value; }
    constexpr bool operator!=(const T rhs) const { return _value != rhs._value; }
    constexpr bool operator <(const T rhs) const { return _value  < rhs._value; }
    constexpr bool operator >(const T rhs) const { return _value  > rhs._value; }
    
    //constexpr operator bool() const { return _value; } // <-- breaks comparison
};

int main()
{
    auto v1 = std::vector<T>{1,2,3};
    auto v2 = std::vector<T>{1,2,9};
    std::cout << "v1 > v2: " << (v1 > v2) << std::endl;
    std::cout << "v1 < v2: " << (v1 < v2) << std::endl;
    return 0;
}

仅从 C++20 开始这似乎是正确的。

std::vector
下面发生了什么变化?

从我的角度来看,这非常可怕。

c++ vector c++20
1个回答
0
投票

C++20 将

<
(以及许多其他标准类)的各个
<=
>
>=
std::vector
运算符替换为单个
<=>

在内部,它尝试使用

<=>
来比较元素,如果类型没有重载
<=>
,则回退到旧的运算符。

由于您有一个非显式

operator bool
,因此应用
<=>
会将两个操作数转换为 bool 并比较它们。解决方法是使
operator bool
explicit
(这通常是一个好主意)(这样
<=>
会失败并且
vector
会退回到旧的运算符),和/或替换
<
<=
,
>
,
>=
<=>
(总的来说这也是一个好主意)。

© www.soinside.com 2019 - 2024. All rights reserved.