簡體   English   中英

為什么map的構造函數允許我們在參數中傳遞一個比較器object?

[英]Why the constructor of the map allow us to pass a comparator object in the parameter?

#include <map>
#include <string>

class A_comparator
{
public:
    template <typename T>
    bool operator()(const T& lhs, const T& rhs) const
    {
        // Defines a custom ordering for the elements in the map
        // ...
    }
};

int main()
{
    A_comparator camp1;
    std::map<int, std::string, A_comparator> map1(camp1);

    map1[1] = "one";
    map1[2] = "two";
    map1[3] = "three";

    A_comparator camp2;
    std::map<int, std::string, A_comparator> map2(camp2);

    map2[1] = "one";
    map2[2] = "two";
    map2[3] = "three";

    // Prints elements in custom order based on their keys
    for (const auto& [key, value] : map1)
        std::cout << key << ": " << value << std::endl;

    std::cout << std::endl;

    for (const auto& [key, value] : map2)
        std::cout << key << ": " << value << std::endl;

    return 0;
}

在此示例中,創建了兩個 std::map 對象 map1 和 map2,每個對象分別使用不同的 A_comparator object、camp1 和 camp2 進行初始化。 map1 和 map2 都使用 A_comparator 比較器來比較它們的鍵,因此它們都將根據 A_comparator class 定義的自定義順序進行排序。使用帶有 std::map 的不同 A_comparator 對象不會影響 map 的行為。

那么為什么 map 的定義不能簡單地像這樣:

....
typedef Compare    key_compare;
key_compare        _comp;
explicit map (): _comp(key_compare(){}
....

上面的代碼將產生相同的行為。

我認為這里要理解的關鍵點是比較器的類型是 map 類型的一部分。因此,如果您使用不同類型的比較器,它就是 map 的不同類型。

現在,有時您希望擁有相同類型的 map,但仍然使用不同的方式來比較 map 的不同實例的鍵。您不能對相同類型的 map 的兩個實例使用不同類型的比較器。

但是,您可以將相同類型比較器的不同實例與相同類型 map 的不同實例一起使用。

例如:

#include <iostream>
#include <map>

struct cmp {
    bool flipped = false;
    bool operator()(const int& a,const int& b) const { 
        if (flipped) return b < a;
        return a < b;
    }
};

void populate_and_print(std::map<int,int,cmp>& m){
    m[1] = 42;
    m[2] = 102;
    for (const auto& e : m) { std::cout << e.first << "\n"; }
}

int main() {
    auto m = std::map<int,int,cmp>(cmp{});
    populate_and_print(m);
    auto n = std::map<int,int,cmp>(cmp{true});
    populate_and_print(n);
}

注意populate_and_print不需要是模板。 mn都是同一類型std::map<int,int,cmp> 比較器的兩個實例屬於同一類型cmp ,但它們進行比較的方式不同。

如果您要編寫不同的比較器cmp2 ,則std::map<int,int,cmp>std::map<int,int,cmp2>是兩種不同的類型。

此外,如果您使用普通的 function 作為比較器,則必須提供一個實例。 考慮:

  bool cmp1(const int& a,const int& b) { return a < b; }
  bool cmp2(const int& a,const int& b) { return b < a; }

這兩個函數的類型都是bool (const int&,const int&) 您不能默認構造一個免費的 function。您需要將 function 指針傳遞給地圖的構造函數。

暫無
暫無

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

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