std :: map比较指针

时间:2013-01-22 00:16:48

标签: c++ map key

如何在下面的示例中实现比较运算符,以便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;
}

1 个答案:

答案 0 :(得分:3)

您的基本问题是您需要实现operator<,以便它不区分ab,并且会为所有不等对象返回一致的结果。

最简单的做法是对指针进行排序,然后对它们进行比较。像

这样的东西
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*>具有总排序。