C++ 指针值的严格弱序

C++ 指针值的严格弱序,c++,set,strict-weak-ordering,C++,Set,Strict Weak Ordering,考虑以下结构: 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可以是空指针。正如std::less在空指针上的行为中所提到的,它是未定义的。以下解决方案是否足够 bool operator<(const Foo

考虑以下结构:

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可以是空指针。正如std::less在空指针上的行为中所提到的,它是未定义的。以下解决方案是否足够

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);
}

bool操作符使用
std::less
就足够了(但是使用
operator会猜测这与
std::less
有相同的问题,因为它们都可能将
nullptr
operator进行比较。链接的答案不会断言
nullptr
上的
std::less
是“未定义的”.上面特别写着“未指定”,这是不同的。这是未指定和未定义行为之间的区别。在大多数实现中,nullptr是一个等于零的值。未指定与未定义是不同的。只要您知道为其编码的平台的nullptr为0,并且这对于您的集合来说是可以的,使用
std::less
是完全正确的很好。std::less只接受2个参数。那么我如何组合它们呢?@fliX:使用
std::tie
没有好方法,因为
std::tuple
被指定为使用内置的
操作符
bool operator<(const Foo& rhs) const {
  if (std::less<>{}(x, rhs.x))
    return true;
  if (std::less<>{}(rhs.x, x))
    return false;
  return std::less<>{}(y, rhs.y);
}