2

我将如何在下面的示例中实现比较运算符,使其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;
}
4

1 回答 1

3

您的基本问题是您需要实现operator<它不区分aand 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(我假设它是一个 C++11 的东西stdext::hash_map是等价的)中工作,那么您需要实现operator==并专门std::hash<>针对您的对象。对于您的专业化,您可能只想散列两个指针并组合值(使用按位异或之类的东西)。


附加到这个问题的非常长的评论线程的要点与 C++ 标准关于指针比较的内容有关。即,比较不是同一对象/数组成员的相同类型的两个对象指针会调用未指定的行为。一般来说,这对于任何具有单一统一内存系统的架构(即您可能使用的任何架构)都无关紧要,但符合标准仍然很好。为此,比较已全部更改为使用std::less<Object*>,因为 C++ 标准保证std::less<T>具有总排序。

于 2013-01-22T00:25:09.807 回答