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