2017-09-12 54 views
3

對於使用find()和operator []訪問地圖的2個地圖,我有一個通用算法。但是,在代碼中的其他地方,我需要遍歷這些映射,並且需要對其中一個映射進行排序,並與另一個進行反向比較。我最終使用了該映射的反向迭代器,但分析表明,在解引用反向迭代器時浪費了大量時間。我試圖做到以下幾點,但它顯然沒有工作:具有不同比較函數的地圖的常用算法

struct Custom 
{ 
    list<double> Doubles; 
    int Integer = 0; 
}; 

typedef map<double, Custom> CustomMap; 
typedef map<double, Custom, std::greater<double>> CustomMapGreater; 

CustomMap A; 
CustomMapGreater B; 

... 

void Algorithm(bool aChosen) 
{ 
    CustomMap* chosenMap; 

    if (aChosen) 
    { 
     chosenMap = &A; 
    } 
    else 
    { 
     chosenMap = &B; // Conversion not possible 
    } 

    // Algorithm that uses chosenMap follows 
    ... 
} 

任何想法,我怎麼能得到這個工作?我有一種感覺,模板可以做些什麼,但我不熟悉泛型編程。

+1

你是怎麼配置的?確保在分析時啓用優化。反向迭代器添加了一層經常可以優化的複雜性。 –

+0

@FrançoisAndrieux我在MSVC中使用了性能嚮導,並通過最大化速度優化進行編譯 –

+1

也許我錯過了一些東西,但是難道您不能僅將地圖類型的算法模板化爲T? –

回答

5

模板的方式是這樣的:

template <typename Map> 
void Algorithm(Map& map) 
{ 
    // ... 
} 

,或者在特定情況下,即使

template <typename Comp> 
void Algorithm(std::map<double, Custom, Comp>& map) 
{ 
    // ... 
} 

然後

void AlgorithmChooser(bool aChosen) 
{ 
    if (aChosen) { 
     Algorithm(A); 
    } else { 
     Algorithm(B); 
    } 
} 
+0

由於'std :: less'和'std :: greater'是兼容的簽名,所以即使沒有模板也可以工作 – Slava

+0

@Slava:有兩個不同的類。 (使用等效的operator()')。比較器可以改爲'bool(*)(const T&,const T&)',並在構造函數中傳遞... – Jarod42

2

您可以使用相同類型的兩個地圖:

typedef map<double, Custom, std::binary_function<const Custom &, const Custom &,bool>> CustomMap; 

CustomMap lessMap(std::less<Custom>()); 
CustomMap greaterMap(std::greater<Custom>()); 

然後您可以將它們作爲相同類型傳遞給函數或將它們分配給指向CustomMap的指針。或者對於C++ 11及更高版本:

typedef map<double, Custom, std::function<bool(const Custom &, const Custom &)>> CustomMap;