STL少运算符和“无效运算符”错误

发布于 2024-12-29 07:38:48 字数 569 浏览 0 评论 0原文

我有一些代码可以在 VS 10.0 中正常编译,但在将一些项目插入下面的订单映射后,我收到“无效运算符 <” Microsoft 调试库中出现错误。我的 less 运算符很简单,只是逐个比较 8 字节字符串。有人知道为什么我会收到此错误吗?

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];

I have some code that compiles fine in VS 10.0 but after inserting a few items into the Orders map below I receive an "invalid operator <" error in Microsoft debug library. My less operator is simple, just compares the 8 byte string char by char. Anyone have any idea why I would receive this error?

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];

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

日裸衫吸 2025-01-05 07:38:49

我相信这里的问题是您比较两个 MY_orderID_t 的方法不是 严格弱顺序,C++ STL 所需的排序关系类型。要成为严格的弱顺序,小于运算符必须具有以下四个属性:

  1. 无自反性:x < x 始终为假。
  2. 反对称:如果 x < y,则 y < x 始终为假。
  3. 传递性:如果 x < y 和 y < z,则x< z 始终为真。
  4. 等价传递性:如果x和y不可比较,并且y和z不可比较,则x和z不可比较。

现在,您的排序不遵守属性 (2) 或 (3)。

*首先,以下内容违反了 (2):

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

*第二,违反了 (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),并且应该使一切正常工作。

希望这有帮助!

I believe that the problem here is that your method of comparing two MY_orderID_t's is not a strict weak order, the type of ordering relation required by the C++ STL. To be a strict weak order, your less-than operator must have the following four properties:

  1. Irreflexivity: x < x is always false.
  2. Antisymmetry: If x < y, then y < x is always false.
  3. Transitivity: If x < y and y < z, then x < z is always true.
  4. Transitivity of Equivalence: If x and y are incomparable and y and z are incomparable, then x and z are incomparable.

Right now, your ordering doesn't obey properties (2) or (3).

*First, (2) is violated by the following:

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

*Second, (3) is violated, because

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

// but 

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

To fix this, instead of using the comparison you currently have, instead use a lexicographical comparison like this one:

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

This comparison is a strict weak ordering and is what's used by all the STL containers by default. Switching to this comparison obeys properties (1) - (4) and should cause everything to work correctly.

Hope this helps!

美人迟暮 2025-01-05 07:38:49

@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;

@templatetypedef tells you what's wrong with your current version.

Here's a much more readable fix:

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;
匿名的好友 2025-01-05 07:38:49

从纯粹语法的角度来看,@templatetypedef 满足了与 map 一起使用的 std::less 特化的要求:

  • 您需要 # include

  • 您在 char orderID[8];MY_orderID_t; 之间缺少 }

    下一行的

  • 和:

    struct std::less;
    {
         /* ... */
    };
    

    应该是:

    命名空间 std {
    模板>>
    struct less;
    {
        /* ... */
    };
    }
    

@templatetypedef addresses the requirements for a std::less specialization to be used with map, from a purely syntactical point of view:

  • You need to #include <functional> and <map>

  • You are missing } between char orderID[8]; and MY_orderID_t; on the next line.

  • and:

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

    should be:

    namespace std {
    template <>
    struct less<MY_orderID_t>
    {
        /* ... */
    };
    }
    
爺獨霸怡葒院 2025-01-05 07:38:49

除了我目前没有看到的任何其他可能的错误之外,不允许使用此构造:

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

std::less 已经是一种类型,因此您不能将其重新定义为另一种类型。

Besides any other possible errors, which I don't see at the moment, this construct is not allowed:

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

std::less is already a type, so you cannot redefine it as another type.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文