2012-01-27 36 views
14

Tôi có một số mã biên dịch tốt trong VS 10.0 nhưng sau khi chèn một vài mục vào bản đồ Đơn hàng bên dưới, tôi nhận được lỗi "toán tử không hợp lệ <" trong thư viện gỡ lỗi của Microsoft. Toán tử ít của tôi là đơn giản, chỉ so sánh chuỗi char 8 byte của char. Bất cứ ai có bất kỳ ý tưởng tại sao tôi sẽ nhận được lỗi này?STL ít toán tử và lỗi "toán tử không hợp lệ <"

Cảm ơn, Mike

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

Trả lời

0

Bên cạnh bất kỳ lỗi nào khác có thể có, mà tôi không thấy vào lúc này, cấu trúc này không được phép:

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

std::less đã là một loại, vì vậy bạn không thể xác định lại nó như một loại khác.

+0

Và [bài này khác] (http://stackoverflow.com/questions/2282349/specialization-of-templateclass-tp-struct-stdless-in- không gian tên khác nhau) cho thấy đúng cách để chuyên 'std :: less'. –

27

Tôi tin rằng vấn đề ở đây là phương pháp của bạn so sánh hai MY_orderID_t 's không phải là một strict weak order, loại đặt hàng liên quan theo yêu cầu của STL C++. Để trở thành một trật tự nghiêm ngặt yếu, kém hơn so với nhà điều hành của bạn phải có bốn thuộc tính sau:

  1. Irreflexivity: x < x luôn luôn là sai.
  2. Chống đối xứng: Nếu x < y, thì y < x luôn là sai.
  3. Độ nhạy: Nếu x < y và y < z, thì x < z luôn đúng.
  4. Độ tương đương của tương đương: Nếu x và y là không thể so sánh và y và z là không thể so sánh, thì x và z là không thể so sánh.

Ngay bây giờ, đơn đặt hàng của bạn không tuân theo các thuộc tính (2) hoặc (3).

* Thứ nhất, (2) bị vi phạm bởi những điều sau đây:

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

* Thứ hai, (3) được vi phạm, vì

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

// but 

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

Để sửa lỗi này, thay vì sử dụng sự so sánh bạn hiện có, thay vì sử dụng một lexicographical comparison như thế này một:

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

So sánh này là một trật tự yếu nghiêm ngặt và là những gì được sử dụng bởi tất cả các container STL theo mặc định. Chuyển sang so sánh này tuân theo các thuộc tính (1) - (4) và sẽ khiến mọi thứ hoạt động chính xác.

Hy vọng điều này sẽ hữu ích!

+0

Để biết thêm chi tiết, hãy xem bài viết tuyệt vời này: [Order I Say!] (Http://cpp-next.com/archive/2010/02/order-i-say/). – ildjarn

3

@templatetypedef giải quyết các yêu cầu cho một chuyên môn hóa std::less được sử dụng với map, từ một quan điểm hoàn toàn cú pháp của xem:

  • Bạn cần phải #include<functional><map>

  • Bạn đang thiếu } giữa char orderID[8];MY_orderID_t; trên dòng tiếp theo.

  • và:

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

    nên là:

    namespace std { 
    template <> 
    struct less<MY_orderID_t> 
    { 
        /* ... */ 
    }; 
    } 
    
5

@templatetypedef cho bạn biết những gì xảy ra với phiên bản hiện tại của bạn.

Dưới đây là một nhiều dễ đọc hơn sửa chữa:

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; 
Các vấn đề liên quan