2017-09-12 23 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;