当提供了operator<重载时,为什么std::tuple比较调用operator bool

fel*_*lix 7 c++ templates c++20

#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;
}
Run Code Online (Sandbox Code Playgroud)

我正在使用 C++20 进行编译。

线路static_assert(std::tie(c) < std::tie(d));会失败。事实证明,在比较c和时doperator bool调用的是 ,而不是operator<。为什么operator bool首先要参与其中?

我觉得这很令人惊讶。这是故意的还是错误?

康桓瑋*_*康桓瑋 9

当比较两个tuple<T>名为t1和 的对象时t2operator<=>重载 fortuple将用于在类型满足get<0>(t1) <=> get<0>(t2)时比较元素;否则,它将使用Tthree_\xc2\xadway_\xc2\xadcomparableoperator<.

\n

由于Y可以隐式转换为bool,这会产生y <=> y一个有效的表达式并满足three_\xc2\xadway_\xc2\xadcomparable,这样std::tie(c) < std::tie(d)(意外地)调用bool(c) <=> bool(d)(意外地)在您的示例中

\n