1. 程式人生 > >使用使用者自定義型別作為std::map的…

使用使用者自定義型別作為std::map的…

有時候我們想把使用者自定義型別作為std::map的鍵值。
方法一)最簡單的方法就是實現該自定義型別的<操作符,程式碼如下:
class Foo
{
public:
    Foo(int num_)
        : num(num_)
    {
    }
    bool operator < (const Foo & cmp) const
    {
        return num < cmp.num;
    }  
    int num;   
};
之後就可以使用Foo作為map的key了:
map<Foo, int> dict; // 該句等同於map<Foo, int, std::less<Foo> > dict;
dict[Foo(1)] = 1;
不過有時候,這招不好使,比如對下面的Foo2:
typedef std::pair<Foo, int> Foo2;
方法二)定義一個比較操作符,使用它作為map的模板引數,程式碼如下:
class Foo2Comparator
{
public:
    bool operator()(const Foo2& key1, const Foo2& key2) const
    {
        if (key1.first < key2.first)
        {
            return true;
        }
        else if (key2.first < key1.first)
        {
            return false;
        }
        else
        {
            return key1.second < key2.second;
        }
    }
};
這時候可以使用Foo2作為map的key了:
map<Foo2, int, Foo2Comparator> dict2;
dict2[Foo2(Foo(1), 100)] = 1;
方法三)為使用者自定義型別特化std::less,程式碼如下:
namespace std
{
template <>
struct less<Foo2>
    : public binary_function <Foo2, Foo2, bool>
{
    bool operator()(const Foo2& key1, const Foo2& key2) const
    {
        if (key1.first < key2.first)
        {
            return true;
        }
        else if (key2.first < key1.first)
        {
            return false;
        }
        else
        {
            return key1.second < key2.second;
        }
    }
};
}
使用這種方法,宣告map時無需指定比較函式物件,因為預設的比較物件就是std::less<T>,
map<Foo2, int> dict2;
dict2[Foo2(Foo(1), 100)] = 3;
======================================================
三種方法裡面我最喜歡第二種,雖然使用起來略微複雜(多了一個模板引數),但最為明確清晰。
另外如果使用std::pair<T1, T2>作為map的key,若T1、T2是原始型別,那麼使用預設的std::less<std::pair<T1, T2> >一般就ok了,沒啥必要去自己折騰。
typedef std::pair<double, int> Pos;
std::map<Pos, int> dict3;
dict3[Pos(1.1, 10)] = 100;