c++ 为什么在提供operator〈overload时std::tuple比较调用运算符bool

jmp7cifd  于 2023-02-06  发布在  其他
关注(0)|答案(1)|浏览(121)
#include <tuple>

struct X {
    int i = 0;
    friend constexpr bool operator<(const X &l, const X &r) noexcept {
        return l.i < r.i;
    }
};

struct Y {
    int i = 0;
    constexpr operator bool() const noexcept {
        return i != 0;
    }
    friend constexpr bool operator<(const Y &l, const Y &r) noexcept {
        return l.i < r.i;
    }
};

int main() {
    constexpr X a{1}, b{2};
    static_assert(std::tie(a) < std::tie(b));

    constexpr Y c{1}, d{2};
    static_assert(c < d);
    // assert failed
    // static_assert(std::tie(c) < std::tie(d));

    return 0;
}

我正在用C++20编译。
static_assert(std::tie(c) < std::tie(d));行将失败,原来在比较cd时,调用的是operator bool,而不是operator<,为什么operator bool一开始会参与进来呢?
我觉得这很奇怪。这是故意的还是一个错误?

jjjwad0x

jjjwad0x1#

当比较两个tuple<T>时,命名为t1t2tupleoperator<=>重载将在类型T满足three_­way_­comparable时使用get<0>(t1) <=> get<0>(t2)来比较元素;否则,它将使用operator<
由于Y可以隐式转换为bool,因此y <=> y是一个有效的表达式,并且满足three_­way_­comparable,从而std::tie(c) < std::tie(d)(意外地)调用了示例中的bool(c) <=> bool(d)

相关问题