【发布时间】:2019-06-09 15:20:24
【问题描述】:
考虑以下结构:
struct Foo {
const Bar* x;
const Bar* y;
Foo(const Bar* _x, const Bar* _y = nullptr) : x(_x), y(_y) { assert(x); }
}
我们如何在 x 和 y 上定义严格的弱排序,以便对象可以在 std::set 中使用?请注意,y 可以是空指针。正如Using std::less with nullptr 中提到的那样,std::less 在空指针上的行为是 undefined 未指定的。以下解决方案是否足够?
bool operator<(const Foo& rhs) const {
uintptr_t numX = reinterpret_cast<uintptr_t>(x);
uintptr_t numY = reinterpret_cast<uintptr_t>(y);
uintptr_t numRhsX = reinterpret_cast<uintptr_t>(rhs.x);
uintptr_t numRhsY = reinterpret_cast<uintptr_t>(rhs.y);
return std::tie(numX, numY) < std::tie(numRhsX, numRhsY);
}
编辑:如果不是正确的方法是什么(例如如何将 std::less 与 std::tie 结合)?
【问题讨论】:
-
我猜这与
std::less有相同的问题,因为他们都可能将nullptr与链接问题说未指定的operator<进行比较。 -
链接的答案确实not断言
nullptr上的std::less是“未定义”。它特别说“未指定”,这是不同的。 -
This question 探讨了未指定和未定义行为之间的区别。
-
在大多数实现中,nullptr 是一个等于零的值。
-
未指定与未定义不同。只要您知道要为其编码的平台的 nullptr 为 0,这对您的设置来说是可以的,使用
std::less就可以了。
标签: c++ set strict-weak-ordering