2012-12-18 66 views
5

std :: map的比較方法在創建和初始化後可以更改嗎? 或者可能只有在它被創建後?初始化後std :: map change key_comp

我想改變一個包含我無法更改定義的映射的類的行爲。我想通過傳遞另一張地圖來改變它的比較行爲。

+0

您是否在此處看到一個函數以允許您直接執行此操作:http://en.cppreference.com/w/cpp/container/map?如果不是,那麼答案是否定的... – Nim

+2

這是一個模板參數,所以它必須在編譯時修復。改變它會改變容器的類型。 – v154c1

回答

4

也許是可能的,這是未經測試:

  1. 定義自己的比較,其內部有一個指針指向真正落實比較功能
  2. 的傳遞了這樣的一個實例的構造地圖(你必須使用這個比較器輸入地圖)
  3. 設置真正的實現後(使用地圖之前),如果你設置它後,你不知道內部的影響...

已測試,並且可以做上面的,但是改變比較功能如果在樹中的項目可能是災難性的......

反正 - 這一切聽起來太腥....

+0

沒關係。地圖是空的。 – djWann

+0

@djWann我認爲每次通過函數指針調用比較的開銷會顯着減慢'map'操作,如果你關心的話。 – rici

+0

@djWann如果地圖是空的,爲什麼不使用一個新的?要麼是兩個完全不同的對象,要麼只要比較器是相同的簽名:'my_map = std :: map <...>(&new_compare);' – rioki

1

這是不可能的。但是,您可以使用替代比較標準創建新地圖,並使用兩個迭代器構造函數使用第一個元素來實例化地圖。

bool C1(const K&, const K&); 
bool C2(const K&, const K&); 

std::map<K, V, C1> orig; 
.... 
std::map<K, V, C2> alternative(orig.begin(), orig.end()); 
1

不,這是不可能的,因爲它是編譯到通過模板參數地圖。

請參閱:http://www.cplusplus.com/reference/map/map/比較是你在找什麼。

你想做什麼?

既然您掌握了您正在用作Key的類,則可以實現<運算符或比較函數以對上下文作出反應。由於您可以將完全構建的對象作爲比較函數傳遞給constructor,因此應該可以將所有內容都傳遞給實現依賴於上下文的同情。問題是,你爲什麼要?

這是一個壞主意在運行時更改std :: map的比較,因爲它會導致未定義的行爲。簡單地基於std :: map的內容是「排序」(可能是一個RB樹)的事實。如果您更改排序功能,您將突然改變邏輯順序;但地圖不會神奇地重新排序。下一次插入或查找電話可能不會達到您的預期。

2

不,這是不可能的。比較器是地圖的類型的一部分。問題與詢問您是否可以更改int來存儲浮點數無關。

更重要的是,比較器提供的順序是映射內部結構的組成部分。如果您要更改排序,則數據結構將不再處於一致狀態。唯一可行的辦法是重建從舊地圖的元素的新地圖相對於新訂單,但是這已經成爲可能:

std::map<T, V, Comp1> m1 = /* ... */; 
std::map<T, V, Comp2> m2(m1.begin(), m1.end()); 

或者,您也可以使std::map<std::reference_wrapper<T const>, std::reference_wrapper<V>, Comp2>類型的第二圖,並引用來填充它到原始地圖,但按照Comp2排序。在這種情況下,您自己有責任保持這兩個地圖同步。像Boost.Multiindex這樣的高級容器可以以安全的方式爲您做到這一點。

相關問題