簡體   English   中英

是不是可以在結構中使用stl map?

[英]Is it impossible to use stl map with struct?

struct Node
{
 int a;
 int b;
};

Node node;
node.a = 2;
node.b = 3;

map<int, int> aa;
aa[1]=1; //O.K.

map<Node, int> bb;
bb[node]=1; //Compile Error

當我嘗試將結構映射到int時,它給了我一個編譯錯誤。 為什么? 謝謝!

對於可用作地圖中的鍵的東西,您必須能夠使用operator<()進行比較。 您需要將這樣的運算符添加到節點類:

struct Node
{
 int a;
 int b;

 bool operator<( const Node & n ) const {
   return this->a < n.a;   // for example
 }
};

當然,真正的運算符所做的取決於比較對於你的結構實際意味着什么。

你必須告訴std :: map如何比較Node對象。 默認情況下,它嘗試使用小於運算符。 但是你沒有為Node提供任何運算符。 最簡單的解決方案是提供一個。

自由功能示例:

bool operator<(Node const& n1, Node const& n2)
{
    return n1.a<n2.a || (n1.a==n2.a && n1.b<n2.b);
}

注意,對於任何一對節點對象x,y與!(x<y)!(y<x) ,映射將x和y視為相等(相同的鍵)。

您需要定義less-than運算符以啟用Node類型的比較:

struct Node
{
 int a;
 int b;
};

bool operator<(Node const& n1, Node const& n2)
{  
   // TODO: Specify condition as you need
   return ... ;
}

在這里,您可以檢查LessThan Comparable對於用戶定義類型的含義。

替代解決方案是基於std :: binary_function定義仿函數。 從設計的角度來看,此選項具有優勢,因為比較與Node類有效地分離。 這使得可以定義專門用不同比較條件(仿函數)的地圖。

#include <map>

struct Node
{
 int a;
 int b;
};

struct NodeLessThan
    : public std::binary_function<Node, Node, bool>
{
    bool operator() (Node const& n1, Node const& n2) const
    {
        // TODO: your condition
        return n1.a < n2.a;
    }
};

int main()
{
    Node node;
    node.a = 2;
    node.b = 3;

    typedef std::map<Node, int, NodeLessThan> node_map_t;
    node_map_t bb;
    bb[node] = 1;
}

因此,您可以定義比NodeLessThan更多的比較,例如使用不同的條件或僅比較Node::a另一個比較兩個組件, Node::aNode::b 然后,定義不同類型的地圖:

typedef std::map<Node, int, NodeLessThan>    node_map_t;
typedef std::map<Node, int, NodeLessThanByA> node_map_a_t;

這種解耦不那么具有侵入性(根本不接觸Node類),並且有利於實現更具可擴展性的解決方案。

如果您不需要按鍵對數據進行排序,則可以使用新的unordered_map:

#include <unordered_map>

... 

std::tr1::unordered_map<Node, int> aa;  // Doesn't require operator<(Node, Node)

你需要一個最近的編譯器才能工作。

更新正如Neil所指出的,如果你想要一個帶有Node鍵的unordered_map,你需要一個專門的哈希函數。

struct NodeHash : std::unary_function<Node, size_t>
{ 
    size_t operator()(Node const & node) const
    {
        return static_cast<size_t>(node.a + 1) * static_cast<size_t>(node.b + 1);
    }
};

然后地圖變成:

 std::tr1::unordered_map<Node, int, NodeHash> aa;

另外,正如sellibitze所說,在哈希沖突的情況下需要運算符==來比較密鑰:

bool operator==(const Node & lhs, const Node & rhs)
{
    return lhs.a == rhs.a && rhs.b == rhs.b;
}

所以我想std :: map畢竟更容易使用。

你能否發布編譯錯誤 - 他們打算告訴 ,有什么問題

我猜你的錯誤發生,因為Node沒有實現地圖所需的比較運算符,以便識別它的元素。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM