2016-10-01 41 views
1

我已经定义了一个类,它维护一个有序映射到其他数据结构的映射。根据用例,我希望其他的按升序或降序排列。受比较器支配的数据结构

struct Book { 
    std::map<double, Level> levels; 

    // More complexity ... 

    void process(Tick &t); 

    const unsigned amount; 

    // More stuf ... 

    Book(const unsigned amount) : levels(), id_price() {} 

}; 

理想情况下,这应该在Book的构造函数中指定。例如,我可以通过std::less<double>()但这不起作用,因为我不能使用变量来声明地图levels,对不对?它会与模板一起工作吗?我不想让它类型通用。它应该是双倍的,不会增加不必要的复杂性。想法?

+0

模板可能是要走的路。 –

+0

你有没有尝试过任何东西?要求_“任何想法?”_听起来太宽泛,不能在这里问。这可能会变成无休止的讨论,这是我们不想在这里。该网站相当简洁的常见问题,如问题和答案对。你也可能想阅读[here](http://stackoverflow.com/help/asking)。 –

+0

只能在比较类型上进行参数设置。 –

回答

2

你可以定义你的地图使用自定义比较

struct Compare 
{ 
    bool operator()(double l, double r) const { 
     return cmp(l, r); 
    } 

    std::function<bool(double, double)> cmp; 
}; 

然后,你定义你的地图如下:

std::map<double, Level, Compare> levels; 

和构造

template<typename T> 
Book(T comparator) : levels(Compare{comparator}) {} 

然后你可以用你想要的任何比较器初始化你的地图

Book a(std::less<>{}); 

如果您不想要std::function的开销,您可以在比较器中实现更严格的逻辑。

+1

比较器不应该是双倍的吗? – joachim

+1

它应该。谢谢!我猜这个编辑框不适合一个好的IDE。 – krzaq

+0

@joachim:使用'Book a(std :: less <>());'在本例中命中[最令人头疼的解析](https://en.wikipedia.org/wiki/Most_vexing_parse)。如果你有更多的构造函数参数不能以相同的方式误解,那么它很可能是好的。 – krzaq

3

您可以沿着这些路线定义自定义比较:

class comparator { 

public: 

     bool descending; 

     comparator(bool descending) : descending(descending) {} 

     bool operator()(double a, double b) const 
     { 
      return descending ? b < a:a < b; 
     } 
}; 

然后,在你的类,定义你的地图中指定该比较器类:

std::map<double, Level, comparator> levels; 

你的构造函数则需要明确初始化该比较器,并用它来初始化你班级的地图。 std::map的构造函数接受一个可选参数,该参数传递地图将使用的比较器类的实例。然后,对于您的Book的每个实例,其构造函数可以指定levels将被排序的方式。

P.S. A doublepoor choice for a map key,但这将是一个不同的问题。