#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));
行将失败,原来在比较c
和d
时,调用的是operator bool
,而不是operator<
,为什么operator bool
一开始会参与进来呢?
我觉得这很奇怪。这是故意的还是一个错误?
1条答案
按热度按时间jjjwad0x1#
当比较两个
tuple<T>
时,命名为t1
和t2
,tuple
的operator<=>
重载将在类型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)
。