14

VS 10.0 で正常にコンパイルされるコードがいくつかありますが、以下の Orders マップにいくつかのアイテムを挿入した後、Microsoft デバッグ ライブラリで「無効な演算子 <」エラーが発生します。私の less 演算子は単純で、8 バイト文字列の char を char ごとに比較するだけです。なぜこのエラーが発生するのか、誰にも分かりますか?

typedef struct MY_orderID_t
{
    char orderID[8];
} MY_orderID_t;

struct std::less<MY_orderID_t>
{ 
   bool operator()(const MY_orderID_t& k1, const MY_orderID_t& k2) const
   {
       for( int i=0; i < 8; i++ )
       {
           if( k1.orderID[i] < k2.orderID[i] )
           return( true );
       }
       return( false );
   }
};

std::map< MY_orderID_t, MY_order_t > Orders[5];
4

4 に答える 4

27

ここでの問題は、2 つの を比較する方法が、C++ STL で必要とされる順序関係のタイプである厳密な弱い順序MY_orderID_tではないことだと思います。厳密に弱い順序であるためには、小なり演算子に次の 4 つのプロパティが必要です。

  1. 非反射性: x < x は常に false です。
  2. 非対称性: x < y の場合、y < x は常に false です。
  3. 推移性: x < y かつ y < z の場合、x < z は常に true です。
  4. 等価性の推移性: x と y が比較不能であり、y と z が比較不能である場合、x と z は比較不能です。

現在、順序付けはプロパティ (2) または (3) に従っていません。

※まず、(2)は以下の場合に違反します。

(0, 4) < (2, 2) 
(2, 2) < (0, 4)

*2番目の(3)は違反です。

(0, 1) < (2, 0) < (-1, 1)

// but 

(0, 1) < (-1, 1) // Fail

これを修正するには、現在使用している比較を使用する代わりに、次のような辞書式比較を使用します。

return std::lexicographical_compare(k1.orderID.begin(), k1.orderID.end(),
                                    k2.orderID.begin(), k2.orderID.end());

この比較は厳密な弱い順序付けであり、デフォルトですべての STL コンテナーによって使用されます。この比較に切り替えると、プロパティ (1) ~ (4) に従い、すべてが正しく機能するようになります。

お役に立てれば!

于 2012-01-27T22:14:55.827 に答える
5

@templatetypedef は、現在のバージョンの問題点を教えてくれます。

より読みやすい修正を次に示します。

struct MY_orderID_type
{
    char orderID[8];
    bool operator<(const MY_orderID_type& other) const
    { return memcmp(orderID, other.orderID, 8) < 0; }
};

std::map< MY_orderID_type, MY_order_type > Orders;
于 2012-01-27T22:19:45.933 に答える
3

@templatetypedef は、純粋に構文的な観点から、std::less特殊化を で使用するための要件に対応しています。map

  • あなたがする必要が#include <functional>あり、<map>

  • 次の行との}間が抜けています。char orderID[8];MY_orderID_t;

  • と:

    struct std::less<MY_orderID_t>
    {
         /* ... */
    };
    

    次のようにする必要があります。

    namespace std {
    template <>
    struct less<MY_orderID_t>
    {
        /* ... */
    };
    }
    
于 2012-01-27T22:19:10.340 に答える
0

現時点では見られないその他の考えられるエラーに加えて、この構成は許可されていません。

struct std::less<MY_orderID_t>
{ /**/ }

std::lessはすでに型であるため、別の型として再定義することはできません。

于 2012-01-27T22:10:59.620 に答える