如何在下面的示例中实现比较运算符,以便ObjectPair( &a, &b )
等于ObjectPair( &b, &a )
?另外,我如何使用stdext::hash_map
代替std::map
?
struct ObjectPair
{
public:
ObjectPair( Object* objA, Object* objB )
{
A = objA;
B = objB;
}
bool operator<( const ObjectPair& pair ) const
{
// ???
}
Object* A;
Object* B;
};
int main()
{
std::map< ObjectPair, int > pairMap;
Object a;
Object b;
pairMap[ ObjectPair(&a, &b) ] = 1;
pairMap[ ObjectPair(&b, &a) ]++;
/// should output 2
std::cout<< pairMap[ ObjectPair( &a, &b ) ] << std::endl;
return 0;
}
答案 0 :(得分:3)
您的基本问题是您需要实现operator<
,以便它不区分a
和b
,并且会为所有不等对象返回一致的结果。
最简单的做法是对指针进行排序,然后对它们进行比较。像
这样的东西bool operator<(const ObjectPair& pair) const {
// Technically < is unspecified on most object pointers
// but std::less<T> is guaranteed to have a total ordering
std::less<Object*> comp;
Object *ourlow = std::min(a, b, comp);
Object *ourhigh = std::max(a, b, comp);
Object *theirlow = std::min(pair->a, pair->b, comp);
Object *theirhigh = std::max(pair->a, pair->b, comp);
if (comp(ourlow, theirlow)) return true;
if (comp(theirlow, ourlow)) return false;
return comp(ourhigh, theirhigh);
}
return false;
}
当然,假设Object
不可排序,因此我们只关心指针值是否相同。如果Object
本身有排序,那么您应该拨打Object::operator<()
而不是仅仅在指针上使用<
,即if (*ourlow < *theirlow)
为了使这个工作在std::unordered_map
(我假设stdext::hash_map
是等价的C ++ 11,那么你需要实现{{1} }以及为您的对象专门化operator==
。对于你的专业化,你可能只想散列两个指针并组合这些值(使用像bitwise-xor这样的东西)。
这个问题附带的真正长评论主题的要点与C ++标准关于指针比较的内容有关。也就是说,比较两个不属于同一对象/数组的相同类型的对象指针会调用未指定的行为。一般来说,这对于任何具有单一统一内存系统的架构(即您可能使用的任何架构)都无关紧要,但仍然很容易符合标准。为此,比较已全部更改为使用std::hash<>
,因为C ++标准保证std::less<Object*>
具有总排序。