[英]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
不需要是模板。 m
和n
都是同一類型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.