[英]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::a
和Node::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.