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<ことです。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)


これを a で機能させるには(これは C++11 のものであり、これは同等であるとstd::unordered_map想定しています)、オブジェクトを実装するだけでなく、特化する必要があります。特殊化のために、2 つのポインターをハッシュし、値を結合することもできます (bitwise-xor などを使用)。stdext::hash_mapoperator==std::hash<>


この質問に添付された非常に長いコメント スレッドの要点は、ポインターの比較について C++ 標準が述べていることと関係があります。つまり、同じオブジェクト/配列のメンバーではない同じ型の 2 つのオブジェクト ポインターを比較すると、未規定の動作が呼び出されます。一般に、これは単一のユニファイド メモリ システムを備えたアーキテクチャ (つまり、使用する可能性が高いアーキテクチャ) では問題になりませんが、それでも標準に準拠していることは望ましいことです。そのために、比較はすべて use に変更されました。これは、C++ 標準が に完全な順序付けがあるstd::less<Object*>ことを保証しているためです。std::less<T>

于 2013-01-22T00:25:09.807 に答える